-module(graded@internal@checker). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/graded/internal/checker.gleam"). -export([build_scc_ids/4, build_function_map/1, check/6, infer_with_returns/6, infer/6, closure_field_operator/6]). -export_type([local_cache/0, memo/0]). -if(?OTP_RELEASE >= 27). -define(MODULEDOC(Str), -moduledoc(Str)). -define(DOC(Str), -doc(Str)). -else. -define(MODULEDOC(Str), -compile([])). -define(DOC(Str), -compile([])). -endif. ?MODULEDOC(false). -type local_cache() :: {local_cache, gleam@dict:dict(binary(), integer()), gleam@dict:dict(integer(), list(binary())), gleam@set:set(integer())}. -type memo() :: {memo, gleam@dict:dict({binary(), list(binary())}, list({graded@internal@types:resolved_call(), graded@internal@types:effect_term()})), gleam@dict:dict(integer(), list({graded@internal@types:resolved_call(), graded@internal@types:effect_term()})), gleam@dict:dict({binary(), list(binary())}, graded@internal@types:effect_term()), gleam@dict:dict({integer(), list(integer()), list(binary()), list(binary())}, graded@internal@types:effect_term())}. -file("src/graded/internal/checker.gleam", 812). ?DOC(false). -spec collect_reference_warnings( binary(), list(graded@internal@types:resolved_call()), graded@internal@effects:knowledge_base() ) -> list(graded@internal@types:warning()). collect_reference_warnings(Function_name, References, Knowledge_base) -> gleam@list:filter_map( References, fun(Ref) -> case graded@internal@effects:lookup( Knowledge_base, erlang:element(2, Ref) ) of {known, Term} -> Effect_set = graded@internal@effect_term:to_effect_set(Term), case Effect_set =:= graded@internal@types:empty() of true -> {error, nil}; false -> {ok, {untracked_effect_warning, Function_name, erlang:element(2, Ref), erlang:element(3, Ref), Effect_set}} end; unknown -> {error, nil} end end ). -file("src/graded/internal/checker.gleam", 319). ?DOC(false). -spec without_returned_closure(glance:function_()) -> glance:function_(). without_returned_closure(Function) -> case lists:reverse(erlang:element(7, Function)) of [{expression, {fn, _, _, _, _}} | Rest] -> {function, erlang:element(2, Function), erlang:element(3, Function), erlang:element(4, Function), erlang:element(5, Function), erlang:element(6, Function), lists:reverse(Rest)}; _ -> Function end. -file("src/graded/internal/checker.gleam", 2185). ?DOC(false). -spec resolve_argument_effects( graded@internal@types:call_argument(), graded@internal@effects:knowledge_base(), list(graded@internal@types:param_bound()) ) -> graded@internal@types:effect_term(). resolve_argument_effects(Arg, Knowledge_base, Caller_param_bounds) -> case erlang:element(4, Arg) of {function_ref, Name} -> graded@internal@effects:lookup_effects(Knowledge_base, Name); constructor_ref -> graded@internal@effect_term:pure(); {local_ref, Name@1} -> case gleam@list:find( Caller_param_bounds, fun(B) -> erlang:element(2, B) =:= Name@1 end ) of {ok, Bound} -> erlang:element(3, Bound); {error, nil} -> graded@internal@effect_term:unknown() end; {closure, _, _} -> graded@internal@effect_term:unknown(); {choice, _} -> graded@internal@effect_term:unknown(); {returned_operator, _, _} -> graded@internal@effect_term:unknown(); other_expression -> graded@internal@effect_term:unknown() end. -file("src/graded/internal/checker.gleam", 223). ?DOC(false). -spec operator_argument_effect( gleam@dict:dict(integer(), list(graded@internal@types:call_argument())), integer(), integer(), graded@internal@effects:knowledge_base(), list(graded@internal@types:param_bound()) ) -> graded@internal@types:effect_term(). operator_argument_effect( Call_args, Span_start, Callback_position, Knowledge_base, Caller_param_bounds ) -> Args = begin _pipe = gleam_stdlib:map_get(Call_args, Span_start), gleam@result:unwrap(_pipe, []) end, case gleam@list:find( Args, fun(A) -> erlang:element(2, A) =:= Callback_position end ) of {ok, Arg} -> resolve_argument_effects(Arg, Knowledge_base, Caller_param_bounds); {error, nil} -> graded@internal@effect_term:unknown() end. -file("src/graded/internal/checker.gleam", 243). ?DOC(false). -spec curried_operator_application( graded@internal@types:effect_term(), list(integer()), gleam@dict:dict(integer(), list(graded@internal@types:call_argument())), integer(), graded@internal@effects:knowledge_base(), list(graded@internal@types:param_bound()) ) -> graded@internal@types:effect_term(). curried_operator_application( Operator, Callback_positions, Call_args, Span_start, Knowledge_base, Caller_param_bounds ) -> gleam@list:fold( Callback_positions, Operator, fun(Acc, Position) -> {t_app, Acc, operator_argument_effect( Call_args, Span_start, Position, Knowledge_base, Caller_param_bounds )} end ). -file("src/graded/internal/checker.gleam", 1524). ?DOC(false). -spec rename_binder(binary(), {binary(), graded@internal@types:effect_term()}) -> graded@internal@types:effect_term(). rename_binder(Binder, Abstraction) -> {Param, Body} = Abstraction, case Param =:= Binder of true -> Body; false -> graded@internal@effect_term:subst( Body, maps:from_list([{Param, {t_var, Binder}}]) ) end. -file("src/graded/internal/checker.gleam", 1493). ?DOC(false). -spec join_operators(list(graded@internal@types:effect_term())) -> graded@internal@types:effect_term(). join_operators(Terms) -> case Terms of [] -> graded@internal@effect_term:unknown(); [Single] -> Single; _ -> Abstractions = gleam@list:filter_map( Terms, fun(Term) -> case Term of {t_abs, Param, Body} -> {ok, {Param, Body}}; _ -> {error, nil} end end ), All_abstractions = erlang:length(Abstractions) =:= erlang:length( Terms ), case Abstractions of [{Binder, _} | _] when All_abstractions -> Bodies = gleam@list:map( Abstractions, fun(_capture) -> rename_binder(Binder, _capture) end ), {t_abs, Binder, join_operators(Bodies)}; [_ | _] -> graded@internal@effect_term:unknown(); [] -> graded@internal@effect_term:normalize({t_union, Terms}) end end. -file("src/graded/internal/checker.gleam", 1434). ?DOC(false). -spec operator_term_for_argument( graded@internal@types:call_argument(), list(integer()), graded@internal@effects:knowledge_base(), list(graded@internal@types:param_bound()), graded@internal@signatures:signature_registry(), fun((graded@internal@types:argument_value(), list(integer()), memo()) -> {{ok, graded@internal@types:effect_term()} | {error, nil}, memo()}), memo() ) -> {graded@internal@types:effect_term(), memo()}. operator_term_for_argument( Arg, Positions, Knowledge_base, Caller_param_bounds, Registry, Lift_operator_arg, Memo ) -> case erlang:element(4, Arg) of {function_ref, Name} -> Body = graded@internal@effects:lookup_effects(Knowledge_base, Name), Operator = begin _pipe = graded@internal@signatures:fn_typed_param_names_ordered( Registry, Name ), gleam@list:fold_right( _pipe, Body, fun(Acc, Param) -> {t_abs, Param, Acc} end ) end, {Operator, Memo}; {choice, Options} -> {Memo@3, Operators} = gleam@list:map_fold( Options, Memo, fun(Memo@1, Option) -> {Op, Memo@2} = operator_term_for_argument( {call_argument, erlang:element(2, Arg), erlang:element(3, Arg), Option}, Positions, Knowledge_base, Caller_param_bounds, Registry, Lift_operator_arg, Memo@1 ), {Memo@2, Op} end ), {join_operators(Operators), Memo@3}; _ -> {Lifted, Memo@4} = Lift_operator_arg( erlang:element(4, Arg), Positions, Memo ), case Lifted of {ok, Operator@1} -> {Operator@1, Memo@4}; {error, nil} -> {resolve_argument_effects( Arg, Knowledge_base, Caller_param_bounds ), Memo@4} end end. -file("src/graded/internal/checker.gleam", 1169). ?DOC(false). -spec operator_spine_arity(graded@internal@types:effect_term()) -> integer(). operator_spine_arity(Term) -> case Term of {t_abs, _, Body} -> 1 + operator_spine_arity(Body); {t_union, Members} -> gleam@list:fold( Members, 0, fun(Max, Member) -> gleam@int:max(Max, operator_spine_arity(Member)) end ); _ -> 0 end. -file("src/graded/internal/checker.gleam", 1093). ?DOC(false). -spec positions_loop(integer(), list(integer())) -> list(integer()). positions_loop(I, Acc) -> case I < 0 of true -> Acc; false -> positions_loop(I - 1, [I | Acc]) end. -file("src/graded/internal/checker.gleam", 1089). ?DOC(false). -spec positions_up_to(integer()) -> list(integer()). positions_up_to(N) -> positions_loop(N - 1, []). -file("src/graded/internal/checker.gleam", 1152). ?DOC(false). -spec discharge_operator(graded@internal@types:effect_term()) -> graded@internal@types:effect_term(). discharge_operator(Operator) -> case Operator of {t_abs, Param, Body} -> discharge_operator( graded@internal@effect_term:normalize( graded@internal@effect_term:subst( Body, maps:from_list( [{Param, graded@internal@effect_term:pure()}] ) ) ) ); Other -> Other end. -file("src/graded/internal/checker.gleam", 1106). ?DOC(false). -spec first_order_arg_effect( graded@internal@types:call_argument(), graded@internal@effects:knowledge_base(), list(graded@internal@types:param_bound()), fun((graded@internal@types:argument_value(), list(integer()), memo()) -> {{ok, graded@internal@types:effect_term()} | {error, nil}, memo()}), memo() ) -> {graded@internal@types:effect_term(), memo()}. first_order_arg_effect( Arg, Knowledge_base, Caller_param_bounds, Lift_operator_arg, Memo ) -> Shadows_param = case erlang:element(4, Arg) of {local_ref, Name} -> gleam@list:any( Caller_param_bounds, fun(B) -> erlang:element(2, B) =:= Name end ); _ -> false end, case {erlang:element(4, Arg), Shadows_param} of {{closure, _, _}, _} -> {Lifted, Memo@1} = Lift_operator_arg( erlang:element(4, Arg), [], Memo ), case Lifted of {ok, Operator} -> {discharge_operator(Operator), Memo@1}; {error, nil} -> {resolve_argument_effects( Arg, Knowledge_base, Caller_param_bounds ), Memo@1} end; {{local_ref, _}, false} -> {Lifted, Memo@1} = Lift_operator_arg( erlang:element(4, Arg), [], Memo ), case Lifted of {ok, Operator} -> {discharge_operator(Operator), Memo@1}; {error, nil} -> {resolve_argument_effects( Arg, Knowledge_base, Caller_param_bounds ), Memo@1} end; {_, _} -> {resolve_argument_effects(Arg, Knowledge_base, Caller_param_bounds), Memo} end. -file("src/graded/internal/checker.gleam", 2154). ?DOC(false). -spec find_arg_at_position( list(graded@internal@types:call_argument()), integer() ) -> gleam@option:option(graded@internal@types:call_argument()). find_arg_at_position(Args, Position) -> _pipe = gleam@list:find( Args, fun(Arg) -> (erlang:element(2, Arg) =:= Position) andalso (erlang:element( 3, Arg ) =:= none) end ), gleam@option:from_result(_pipe). -file("src/graded/internal/checker.gleam", 2146). ?DOC(false). -spec find_arg_by_label(list(graded@internal@types:call_argument()), binary()) -> gleam@option:option(graded@internal@types:call_argument()). find_arg_by_label(Args, Label) -> _pipe = gleam@list:find( Args, fun(Arg) -> erlang:element(3, Arg) =:= {some, Label} end ), gleam@option:from_result(_pipe). -file("src/graded/internal/checker.gleam", 2167). ?DOC(false). -spec param_info( graded@internal@types:qualified_name(), binary(), graded@internal@signatures:signature_registry() ) -> gleam@option:option(graded@internal@signatures:parameter_info()). param_info(Callee_name, Param_name, Registry) -> gleam@option:then( graded@internal@signatures:lookup(Registry, Callee_name), fun(Params) -> By_name = begin _pipe = gleam@list:find( Params, fun(P) -> erlang:element(4, P) =:= {some, Param_name} end ), gleam@option:from_result(_pipe) end, gleam@option:lazy_or( By_name, fun() -> _pipe@1 = gleam@list:find( Params, fun(P@1) -> erlang:element(3, P@1) =:= {some, Param_name} end ), gleam@option:from_result(_pipe@1) end ) end ). -file("src/graded/internal/checker.gleam", 2122). ?DOC(false). -spec find_matching_arg( graded@internal@types:qualified_name(), graded@internal@types:param_bound(), list(graded@internal@types:call_argument()), graded@internal@signatures:signature_registry() ) -> gleam@option:option(graded@internal@types:call_argument()). find_matching_arg(Callee_name, Bound, Args, Registry) -> By_bound_name = find_arg_by_label(Args, erlang:element(2, Bound)), gleam@option:lazy_or( By_bound_name, fun() -> gleam@option:then( param_info(Callee_name, erlang:element(2, Bound), Registry), fun(Param) -> By_param_label = begin _pipe = erlang:element(3, Param), gleam@option:then( _pipe, fun(_capture) -> find_arg_by_label(Args, _capture) end ) end, gleam@option:lazy_or( By_param_label, fun() -> find_arg_at_position(Args, erlang:element(2, Param)) end ) end ) end ). -file("src/graded/internal/checker.gleam", 1357). ?DOC(false). -spec bind_variables( graded@internal@types:qualified_name(), list(graded@internal@types:param_bound()), list(graded@internal@types:call_argument()), graded@internal@effects:knowledge_base(), list(graded@internal@types:param_bound()), graded@internal@signatures:signature_registry(), fun((graded@internal@types:argument_value(), list(integer()), memo()) -> {{ok, graded@internal@types:effect_term()} | {error, nil}, memo()}), memo() ) -> {gleam@dict:dict(binary(), graded@internal@types:effect_term()), memo()}. bind_variables( Callee_name, Callee_bounds, Args, Knowledge_base, Caller_param_bounds, Registry, Lift_operator_arg, Memo ) -> Operator_params = graded@internal@signatures:operator_param_names( Registry, Callee_name ), gleam@list:fold( Callee_bounds, {maps:new(), Memo}, fun(State, Bound) -> {Acc, Memo@1} = State, Matched = find_matching_arg(Callee_name, Bound, Args, Registry), case Matched of {some, Arg} -> {Arg_effects, Memo@2} = case gleam@set:contains( Operator_params, erlang:element(2, Bound) ) of true -> operator_term_for_argument( Arg, graded@internal@signatures:operator_callback_positions( Registry, Callee_name, erlang:element(2, Bound) ), Knowledge_base, Caller_param_bounds, Registry, Lift_operator_arg, Memo@1 ); false -> first_order_arg_effect( Arg, Knowledge_base, Caller_param_bounds, Lift_operator_arg, Memo@1 ) end, Var_names = begin _pipe = erlang:element(3, Bound), _pipe@1 = graded@internal@effect_term:free_vars(_pipe), gleam@set:to_list(_pipe@1) end, Acc@1 = gleam@list:fold( Var_names, Acc, fun(D, Var) -> gleam@dict:insert(D, Var, Arg_effects) end ), {Acc@1, Memo@2}; none -> {Acc, Memo@1} end end ). -file("src/graded/internal/checker.gleam", 280). ?DOC(false). -spec union_of( list({graded@internal@types:resolved_call(), graded@internal@types:effect_term()}) ) -> graded@internal@types:effect_term(). union_of(Pairs) -> graded@internal@effect_term:normalize( {t_union, gleam@list:map(Pairs, fun(Pair) -> erlang:element(2, Pair) end)} ). -file("src/graded/internal/checker.gleam", 270). ?DOC(false). -spec self_referential_bound(binary()) -> graded@internal@types:param_bound(). self_referential_bound(Name) -> {param_bound, Name, {t_var, Name}}. -file("src/graded/internal/checker.gleam", 534). ?DOC(false). -spec memo_key(binary(), gleam@set:set(binary()), local_cache()) -> {binary(), list(binary())}. memo_key(Name, Visited, Cache) -> Scc = gleam_stdlib:map_get(erlang:element(2, Cache), Name), Ancestors = begin _pipe = Visited, _pipe@1 = gleam@set:to_list(_pipe), _pipe@2 = gleam@list:filter( _pipe@1, fun(Ancestor) -> gleam_stdlib:map_get(erlang:element(2, Cache), Ancestor) =:= Scc end ), gleam@list:sort(_pipe@2, fun gleam@string:compare/2) end, {Name, Ancestors}. -file("src/graded/internal/checker.gleam", 2109). ?DOC(false). -spec ordered_fn_typed_param_names(glance:function_()) -> list(binary()). ordered_fn_typed_param_names(Function) -> gleam@list:filter_map( erlang:element(5, Function), fun(Param) -> case {erlang:element(4, Param), erlang:element(3, Param)} of {{some, {function_type, _, _, _}}, {named, Name}} -> {ok, Name}; {_, _} -> {error, nil} end end ). -file("src/graded/internal/checker.gleam", 1989). ?DOC(false). -spec statement_start(glance:statement()) -> integer(). statement_start(Statement) -> case Statement of {use, Location, _, _} -> erlang:element(2, Location); {assignment, Location@1, _, _, _, _} -> erlang:element(2, Location@1); {assert, Location@2, _, _} -> erlang:element(2, Location@2); {expression, Expression} -> erlang:element(2, erlang:element(2, Expression)) end. -file("src/graded/internal/checker.gleam", 1982). ?DOC(false). -spec closure_body_start(list(glance:statement())) -> integer(). closure_body_start(Body) -> case Body of [Statement | _] -> statement_start(Statement); [] -> -1 end. -file("src/graded/internal/checker.gleam", 1827). ?DOC(false). -spec compute_returned_operator_result(graded@internal@types:effect_term()) -> {ok, graded@internal@types:effect_term()} | {error, nil}. compute_returned_operator_result(Operator) -> case Operator of {t_abs, _, _} -> {ok, Operator}; {t_var, _} -> {ok, Operator}; {t_union, _} -> {ok, Operator}; {t_labels, _} -> case Operator =:= graded@internal@effect_term:unknown() of true -> {error, nil}; false -> {ok, Operator} end; t_top -> case Operator =:= graded@internal@effect_term:unknown() of true -> {error, nil}; false -> {ok, Operator} end; {t_app, _, _} -> {error, nil} end. -file("src/graded/internal/checker.gleam", 2644). ?DOC(false). -spec concretize(graded@internal@types:effect_term()) -> graded@internal@types:effect_term(). concretize(Term) -> Bindings = begin _pipe = Term, _pipe@1 = graded@internal@effect_term:free_vars(_pipe), gleam@set:fold( _pipe@1, maps:new(), fun(D, Var) -> gleam@dict:insert(D, Var, graded@internal@effect_term:unknown()) end ) end, graded@internal@effect_term:normalize( graded@internal@effect_term:subst(Term, Bindings) ). -file("src/graded/internal/checker.gleam", 275). ?DOC(false). -spec has_vars(graded@internal@types:effect_term()) -> boolean(). has_vars(Term) -> not gleam@set:is_empty(graded@internal@effect_term:free_vars(Term)). -file("src/graded/internal/checker.gleam", 2636). ?DOC(false). -spec apply_args( graded@internal@types:effect_term(), list(graded@internal@types:effect_term()) ) -> graded@internal@types:effect_term(). apply_args(Operator, Arg_terms) -> gleam@list:fold(Arg_terms, Operator, fun(Acc, Arg) -> {t_app, Acc, Arg} end). -file("src/graded/internal/checker.gleam", 2586). ?DOC(false). -spec is_operator_valued(graded@internal@types:effect_term()) -> boolean(). is_operator_valued(Term) -> case Term of {t_abs, _, _} -> true; {t_union, Members} -> gleam@list:any(Members, fun is_operator_valued/1); _ -> false end. -file("src/graded/internal/checker.gleam", 2609). ?DOC(false). -spec apply_field_operator( graded@internal@types:effect_term(), list(graded@internal@types:call_argument()), graded@internal@effects:knowledge_base(), list(graded@internal@types:param_bound()) ) -> graded@internal@types:effect_term(). apply_field_operator(Operator, Args, Knowledge_base, Caller_param_bounds) -> Arg_terms = begin _pipe = Args, _pipe@1 = gleam@list:sort( _pipe, fun(A, B) -> gleam@int:compare(erlang:element(2, A), erlang:element(2, B)) end ), gleam@list:map( _pipe@1, fun(_capture) -> resolve_argument_effects( _capture, Knowledge_base, Caller_param_bounds ) end ) end, case Operator of {t_union, Members} -> _pipe@2 = Members, _pipe@3 = gleam@list:map( _pipe@2, fun(Member) -> case is_operator_valued(Member) of true -> apply_args(Member, Arg_terms); false -> Member end end ), _pipe@4 = {t_union, _pipe@3}, concretize(_pipe@4); _ -> concretize(apply_args(Operator, Arg_terms)) end. -file("src/graded/internal/checker.gleam", 2531). ?DOC(false). -spec resolve_field_effect( graded@internal@types:type_field_effect(), graded@internal@types:field_call(), gleam@dict:dict(integer(), list(graded@internal@types:call_argument())), graded@internal@effects:knowledge_base(), list(graded@internal@types:param_bound()), graded@internal@signatures:signature_registry(), fun((graded@internal@types:argument_value(), list(integer()), memo()) -> {{ok, graded@internal@types:effect_term()} | {error, nil}, memo()}), memo() ) -> {graded@internal@types:effect_term(), memo()}. resolve_field_effect( Field_effect, Field_call, Call_args, Knowledge_base, Caller_param_bounds, Registry, Lift_operator_arg, Memo ) -> gleam@bool:guard( is_operator_valued(erlang:element(2, Field_effect)), {apply_field_operator( erlang:element(2, Field_effect), begin _pipe = gleam_stdlib:map_get( Call_args, erlang:element(2, erlang:element(4, Field_call)) ), gleam@result:unwrap(_pipe, []) end, Knowledge_base, Caller_param_bounds ), Memo}, fun() -> case {has_vars(erlang:element(2, Field_effect)), erlang:element(4, Field_effect)} of {false, _} -> {erlang:element(2, Field_effect), Memo}; {true, none} -> {concretize(erlang:element(2, Field_effect)), Memo}; {true, {some, Source}} -> Args = begin _pipe@1 = gleam_stdlib:map_get( Call_args, erlang:element(2, erlang:element(4, Field_call)) ), gleam@result:unwrap(_pipe@1, []) end, {Bindings, Memo@1} = bind_variables( Source, erlang:element(3, Field_effect), Args, Knowledge_base, Caller_param_bounds, Registry, Lift_operator_arg, Memo ), {concretize( graded@internal@effect_term:subst( erlang:element(2, Field_effect), Bindings ) ), Memo@1} end end ). -file("src/graded/internal/checker.gleam", 2657). ?DOC(false). -spec syntactic_param_type(glance:function_(), binary()) -> gleam@option:option(binary()). syntactic_param_type(Function, Object) -> case gleam@list:find( erlang:element(5, Function), fun(Param) -> case erlang:element(3, Param) of {named, Name} -> Name =:= Object; {discarded, _} -> false end end ) of {ok, {function_parameter, _, _, {some, {named_type, _, Type_name, _, _}}}} -> {some, Type_name}; _ -> none end. -file("src/graded/internal/checker.gleam", 2478). ?DOC(false). -spec resolve_field_call_by_type( graded@internal@types:field_call(), glance:function_(), graded@internal@effects:knowledge_base(), gleam@dict:dict({integer(), integer()}, girard@types:type()), gleam@dict:dict(integer(), list(graded@internal@types:call_argument())), list(graded@internal@types:param_bound()), graded@internal@signatures:signature_registry(), fun((graded@internal@types:argument_value(), list(integer()), memo()) -> {{ok, graded@internal@types:effect_term()} | {error, nil}, memo()}), memo() ) -> {graded@internal@types:effect_term(), memo()}. resolve_field_call_by_type( Field_call, Function, Knowledge_base, Module_types, Call_args, Caller_param_bounds, Registry, Lift_operator_arg, Memo ) -> Receiver_type = begin _pipe = graded@internal@typeinfo:receiver_type( Module_types, erlang:element(2, erlang:element(5, Field_call)), erlang:element(3, erlang:element(5, Field_call)) ), gleam@option:lazy_or( _pipe, fun() -> _pipe@1 = syntactic_param_type( Function, erlang:element(2, Field_call) ), gleam@option:map( _pipe@1, fun(Type_name) -> {<<""/utf8>>, Type_name} end ) end ) end, case Receiver_type of none -> {graded@internal@effect_term:unknown(), Memo}; {some, {Module, Type_name@1}} -> case graded@internal@effects:lookup_type_field( Knowledge_base, Module, Type_name@1, erlang:element(3, Field_call) ) of {error, nil} -> {graded@internal@effect_term:unknown(), Memo}; {ok, Field_effect} -> resolve_field_effect( Field_effect, Field_call, Call_args, Knowledge_base, Caller_param_bounds, Registry, Lift_operator_arg, Memo ) end end. -file("src/graded/internal/checker.gleam", 2429). ?DOC(false). -spec resolve_field_call( graded@internal@types:field_call(), glance:function_(), graded@internal@effects:knowledge_base(), gleam@dict:dict({integer(), integer()}, girard@types:type()), gleam@dict:dict(integer(), list(graded@internal@types:call_argument())), list(graded@internal@types:param_bound()), graded@internal@signatures:signature_registry(), fun((graded@internal@types:argument_value(), list(integer()), memo()) -> {{ok, graded@internal@types:effect_term()} | {error, nil}, memo()}), memo() ) -> {graded@internal@types:effect_term(), memo()}. resolve_field_call( Field_call, Function, Knowledge_base, Module_types, Call_args, Caller_param_bounds, Registry, Lift_operator_arg, Memo ) -> Field_target = <<<<(erlang:element(2, Field_call))/binary, "."/utf8>>/binary, (erlang:element(3, Field_call))/binary>>, case gleam@list:find( Caller_param_bounds, fun(B) -> erlang:element(2, B) =:= Field_target end ) of {ok, Bound} -> {erlang:element(3, Bound), Memo}; {error, nil} -> resolve_field_call_by_type( Field_call, Function, Knowledge_base, Module_types, Call_args, Caller_param_bounds, Registry, Lift_operator_arg, Memo ) end. -file("src/graded/internal/checker.gleam", 288). ?DOC(false). -spec synthetic_fn_typed_bounds(gleam@set:set(binary())) -> list(graded@internal@types:param_bound()). synthetic_fn_typed_bounds(Fn_typed_params) -> _pipe = Fn_typed_params, _pipe@1 = gleam@set:to_list(_pipe), gleam@list:map(_pipe@1, fun self_referential_bound/1). -file("src/graded/internal/checker.gleam", 1249). ?DOC(false). -spec local_polymorphic_bounds(glance:function_()) -> list(graded@internal@types:param_bound()). local_polymorphic_bounds(Function) -> synthetic_fn_typed_bounds( graded@internal@signatures:fn_typed_params_from_function(Function) ). -file("src/graded/internal/checker.gleam", 1189). ?DOC(false). -spec substitute_local_call_effects( list({graded@internal@types:resolved_call(), graded@internal@types:effect_term()}), graded@internal@types:local_call(), gleam@dict:dict(integer(), list(graded@internal@types:call_argument())), gleam@dict:dict(binary(), glance:definition(glance:function_())), graded@internal@effects:knowledge_base(), list(graded@internal@types:param_bound()), graded@internal@signatures:signature_registry(), fun((graded@internal@types:argument_value(), list(integer()), memo()) -> {{ok, graded@internal@types:effect_term()} | {error, nil}, memo()}), memo() ) -> {list({graded@internal@types:resolved_call(), graded@internal@types:effect_term()}), memo()}. substitute_local_call_effects( Recursive, Local_call, Call_args, Function_map, Knowledge_base, Caller_param_bounds, Registry, Lift_operator_arg, Memo ) -> Any_polymorphic = gleam@list:any( Recursive, fun(P) -> has_vars(erlang:element(2, P)) end ), gleam@bool:guard( not Any_polymorphic, {Recursive, Memo}, fun() -> case gleam_stdlib:map_get( Function_map, erlang:element(2, Local_call) ) of {error, nil} -> {Recursive, Memo}; {ok, Local_definition} -> Bounds = local_polymorphic_bounds( erlang:element(3, Local_definition) ), Args = begin _pipe = gleam_stdlib:map_get( Call_args, erlang:element(2, erlang:element(3, Local_call)) ), gleam@result:unwrap(_pipe, []) end, Callee_name = {qualified_name, <<""/utf8>>, erlang:element(2, Local_call)}, Local_registry = graded@internal@signatures:from_glance_module( <<""/utf8>>, {module, [], [], [], [], [Local_definition]} ), Merged_registry = graded@internal@signatures:merge( Registry, Local_registry ), {Bindings, Memo@1} = bind_variables( Callee_name, Bounds, Args, Knowledge_base, Caller_param_bounds, Merged_registry, Lift_operator_arg, Memo ), Substituted = gleam@list:map( Recursive, fun(Pair) -> {Call, Term} = Pair, {Call, graded@internal@effect_term:normalize( graded@internal@effect_term:subst( Term, Bindings ) )} end ), {Substituted, Memo@1} end end ). -file("src/graded/internal/checker.gleam", 640). ?DOC(false). -spec is_opaque_external(glance:definition(glance:function_())) -> boolean(). is_opaque_external(Definition) -> gleam@list:any( erlang:element(2, Definition), fun(Attribute) -> erlang:element(2, Attribute) =:= <<"external"/utf8>> end ). -file("src/graded/internal/checker.gleam", 1312). ?DOC(false). -spec auto_bounds_from_registry( graded@internal@types:qualified_name(), graded@internal@types:effect_term(), list(graded@internal@types:call_argument()), graded@internal@signatures:signature_registry() ) -> {graded@internal@types:effect_term(), list(graded@internal@types:param_bound())}. auto_bounds_from_registry(Callee_name, Existing_effects, Args, Registry) -> Fn_labels = graded@internal@signatures:fn_typed_param_names( Registry, Callee_name ), gleam@bool:guard( gleam@set:is_empty(Fn_labels), {Existing_effects, []}, fun() -> Tracked_bounds = begin _pipe = Fn_labels, _pipe@1 = gleam@set:to_list(_pipe), _pipe@2 = gleam@list:sort(_pipe@1, fun gleam@string:compare/2), gleam@list:filter_map( _pipe@2, fun(Label) -> Bound = self_referential_bound(Label), case find_matching_arg( Callee_name, Bound, Args, Registry ) of {some, Arg} -> case erlang:element(4, Arg) of {closure, _, _} -> {error, nil}; {choice, _} -> {error, nil}; other_expression -> {error, nil}; _ -> {ok, Bound} end; none -> {error, nil} end end ) end, case Tracked_bounds of [] -> {Existing_effects, []}; _ -> Tracked_vars = gleam@list:map( Tracked_bounds, fun(B) -> {t_var, erlang:element(2, B)} end ), {graded@internal@effect_term:normalize( {t_union, [Existing_effects | Tracked_vars]} ), Tracked_bounds} end end ). -file("src/graded/internal/checker.gleam", 1259). ?DOC(false). -spec substitute_at_call_site( graded@internal@types:resolved_call(), graded@internal@types:effect_term(), gleam@dict:dict(integer(), list(graded@internal@types:call_argument())), graded@internal@effects:knowledge_base(), list(graded@internal@types:param_bound()), graded@internal@signatures:signature_registry(), fun((graded@internal@types:argument_value(), list(integer()), memo()) -> {{ok, graded@internal@types:effect_term()} | {error, nil}, memo()}), memo() ) -> {graded@internal@types:effect_term(), memo()}. substitute_at_call_site( Call, Effect, Call_args, Knowledge_base, Caller_param_bounds, Registry, Lift_operator_arg, Memo ) -> Callee_kb_bounds = graded@internal@effects:lookup_param_bounds( Knowledge_base, erlang:element(2, Call) ), gleam@bool:guard( not has_vars(Effect) andalso (Callee_kb_bounds /= []), {Effect, Memo}, fun() -> Args = begin _pipe = gleam_stdlib:map_get( Call_args, erlang:element(2, erlang:element(3, Call)) ), gleam@result:unwrap(_pipe, []) end, {Effective_effects, Effective_bounds} = case Callee_kb_bounds of [_ | _] -> {Effect, Callee_kb_bounds}; [] -> auto_bounds_from_registry( erlang:element(2, Call), Effect, Args, Registry ) end, gleam@bool:guard( not has_vars(Effective_effects), {Effective_effects, Memo}, fun() -> {Bindings, Memo@1} = bind_variables( erlang:element(2, Call), Effective_bounds, Args, Knowledge_base, Caller_param_bounds, Registry, Lift_operator_arg, Memo ), {graded@internal@effect_term:normalize( graded@internal@effect_term:subst( Effective_effects, Bindings ) ), Memo@1} end ) end ). -file("src/graded/internal/checker.gleam", 2071). ?DOC(false). -spec lift_operator_miss( binary(), glance:function_(), list(binary()), {binary(), list(binary())}, graded@internal@extract:import_context(), gleam@dict:dict(binary(), glance:definition(glance:function_())), graded@internal@effects:knowledge_base(), gleam@set:set(binary()), graded@internal@signatures:signature_registry(), gleam@dict:dict({integer(), integer()}, girard@types:type()), local_cache(), memo() ) -> {graded@internal@types:effect_term(), memo()}. lift_operator_miss( Name, Function, Fn_param_names, Key, Context, Function_map, Knowledge_base, Visited, Registry, Module_types, Cache, Memo ) -> Bounds = gleam@list:map(Fn_param_names, fun self_referential_bound/1), {Body_pairs, Memo@1} = collect_effects( without_returned_closure(Function), Function_map, Context, Knowledge_base, gleam@set:insert(Visited, Name), Bounds, Registry, Module_types, maps:new(), Cache, Memo ), Body_term = union_of(Body_pairs), Operator = gleam@list:fold_right( Fn_param_names, Body_term, fun(Acc, Param) -> {t_abs, Param, Acc} end ), {Operator, {memo, erlang:element(2, Memo@1), erlang:element(3, Memo@1), gleam@dict:insert(erlang:element(4, Memo@1), Key, Operator), erlang:element(5, Memo@1)}}. -file("src/graded/internal/checker.gleam", 2395). ?DOC(false). -spec collapsed_member( binary(), list({graded@internal@types:resolved_call(), graded@internal@types:effect_term()}), gleam@set:set(binary()), gleam@dict:dict(binary(), glance:definition(glance:function_())), graded@internal@extract:import_context(), graded@internal@effects:knowledge_base(), graded@internal@signatures:signature_registry(), gleam@dict:dict({integer(), integer()}, girard@types:type()), local_cache(), memo() ) -> {list({graded@internal@types:resolved_call(), graded@internal@types:effect_term()}), memo()}. collapsed_member( Name, Acc, Scc_set, Function_map, Context, Knowledge_base, Registry, Module_types, Cache, Memo ) -> case gleam_stdlib:map_get(Function_map, Name) of {ok, Definition} -> {Member_effects, Memo@1} = collect_effects( without_returned_closure(erlang:element(3, Definition)), Function_map, Context, Knowledge_base, Scc_set, [], Registry, Module_types, maps:new(), Cache, Memo ), {lists:append(Acc, Member_effects), Memo@1}; {error, nil} -> {Acc, Memo} end. -file("src/graded/internal/checker.gleam", 2356). ?DOC(false). -spec collapsed_scc( integer(), gleam@dict:dict(binary(), glance:definition(glance:function_())), graded@internal@extract:import_context(), graded@internal@effects:knowledge_base(), graded@internal@signatures:signature_registry(), gleam@dict:dict({integer(), integer()}, girard@types:type()), local_cache(), memo() ) -> {list({graded@internal@types:resolved_call(), graded@internal@types:effect_term()}), memo()}. collapsed_scc( Scc, Function_map, Context, Knowledge_base, Registry, Module_types, Cache, Memo ) -> case gleam_stdlib:map_get(erlang:element(3, Memo), Scc) of {ok, Cached} -> {Cached, Memo}; {error, nil} -> Members = begin _pipe = gleam_stdlib:map_get(erlang:element(3, Cache), Scc), gleam@result:unwrap(_pipe, []) end, Scc_set = gleam@set:from_list(Members), {Result, Memo@2} = gleam@list:fold( Members, {[], Memo}, fun(State, Name) -> {Acc, Memo@1} = State, collapsed_member( Name, Acc, Scc_set, Function_map, Context, Knowledge_base, Registry, Module_types, Cache, Memo@1 ) end ), {Result, {memo, erlang:element(2, Memo@2), gleam@dict:insert(erlang:element(3, Memo@2), Scc, Result), erlang:element(4, Memo@2), erlang:element(5, Memo@2)}} end. -file("src/graded/internal/checker.gleam", 2005). ?DOC(false). -spec lift_local_function( binary(), glance:definition(glance:function_()), graded@internal@extract:import_context(), gleam@dict:dict(binary(), glance:definition(glance:function_())), graded@internal@effects:knowledge_base(), gleam@set:set(binary()), graded@internal@signatures:signature_registry(), gleam@dict:dict({integer(), integer()}, girard@types:type()), local_cache(), memo() ) -> {graded@internal@types:effect_term(), memo()}. lift_local_function( Name, Definition, Context, Function_map, Knowledge_base, Visited, Registry, Module_types, Cache, Memo ) -> Function = erlang:element(3, Definition), Fn_param_names = ordered_fn_typed_param_names(Function), Scc = begin _pipe = gleam_stdlib:map_get(erlang:element(2, Cache), Name), gleam@result:unwrap(_pipe, -1) end, case gleam@set:contains(erlang:element(4, Cache), Scc) of true -> {Pairs, Memo@1} = collapsed_scc( Scc, Function_map, Context, Knowledge_base, Registry, Module_types, Cache, Memo ), {union_of(Pairs), Memo@1}; false -> {_, Ancestors} = memo_key(Name, Visited, Cache), Key = {Name, Ancestors}, case gleam_stdlib:map_get(erlang:element(4, Memo), Key) of {ok, Cached} -> {Cached, Memo}; {error, nil} -> lift_operator_miss( Name, Function, Fn_param_names, Key, Context, Function_map, Knowledge_base, Visited, Registry, Module_types, Cache, Memo ) end end. -file("src/graded/internal/checker.gleam", 1913). ?DOC(false). -spec analyze_closure_uncached( list(binary()), list(glance:statement()), list(integer()), graded@internal@extract:import_context(), gleam@dict:dict(binary(), glance:definition(glance:function_())), graded@internal@effects:knowledge_base(), gleam@set:set(binary()), graded@internal@signatures:signature_registry(), gleam@dict:dict({integer(), integer()}, girard@types:type()), gleam@dict:dict(binary(), list(integer())), local_cache(), memo() ) -> {graded@internal@types:effect_term(), memo()}. analyze_closure_uncached( Params, Body, Positions, Context, Function_map, Knowledge_base, Visited, Registry, Module_types, Ambient_operators, Cache, Memo ) -> Synthetic = {function, {span, 0, 0}, <<""/utf8>>, private, [], none, Body}, Bounds = lists:append( gleam@list:map(Params, fun self_referential_bound/1), gleam@list:map( maps:keys(Ambient_operators), fun self_referential_bound/1 ) ), {Body_pairs, Memo@1} = collect_effects( Synthetic, Function_map, Context, Knowledge_base, Visited, Bounds, Registry, Module_types, Ambient_operators, Cache, Memo ), Body_term = union_of(Body_pairs), Callback_params = case Positions of [] -> case Params of [First | _] -> [First]; [] -> [] end; _ -> gleam@list:filter_map( Positions, fun(Position) -> graded@internal@extract:at(Params, Position) end ) end, Operator = gleam@list:fold_right( Callback_params, Body_term, fun(Acc, Param) -> {t_abs, Param, Acc} end ), {Operator, Memo@1}. -file("src/graded/internal/checker.gleam", 1861). ?DOC(false). -spec analyze_closure( list(binary()), list(glance:statement()), list(integer()), graded@internal@extract:import_context(), gleam@dict:dict(binary(), glance:definition(glance:function_())), graded@internal@effects:knowledge_base(), gleam@set:set(binary()), graded@internal@signatures:signature_registry(), gleam@dict:dict({integer(), integer()}, girard@types:type()), gleam@dict:dict(binary(), list(integer())), local_cache(), memo() ) -> {graded@internal@types:effect_term(), memo()}. analyze_closure( Params, Body, Positions, Context, Function_map, Knowledge_base, Visited, Registry, Module_types, Ambient_operators, Cache, Memo ) -> Key = {closure_body_start(Body), Positions, gleam@list:sort( maps:keys(Ambient_operators), fun gleam@string:compare/2 ), gleam@list:sort(gleam@set:to_list(Visited), fun gleam@string:compare/2)}, case gleam_stdlib:map_get(erlang:element(5, Memo), Key) of {ok, Cached} -> {Cached, Memo}; {error, nil} -> {Operator, Memo@1} = analyze_closure_uncached( Params, Body, Positions, Context, Function_map, Knowledge_base, Visited, Registry, Module_types, Ambient_operators, Cache, Memo ), {Operator, {memo, erlang:element(2, Memo@1), erlang:element(3, Memo@1), erlang:element(4, Memo@1), gleam@dict:insert(erlang:element(5, Memo@1), Key, Operator)}} end. -file("src/graded/internal/checker.gleam", 1544). ?DOC(false). -spec build_lift_operator_arg( graded@internal@extract:import_context(), gleam@dict:dict(binary(), glance:definition(glance:function_())), graded@internal@effects:knowledge_base(), gleam@set:set(binary()), graded@internal@signatures:signature_registry(), gleam@dict:dict({integer(), integer()}, girard@types:type()), gleam@dict:dict(binary(), list(integer())), local_cache() ) -> fun((graded@internal@types:argument_value(), list(integer()), memo()) -> {{ok, graded@internal@types:effect_term()} | {error, nil}, memo()}). build_lift_operator_arg( Context, Function_map, Knowledge_base, Visited, Registry, Module_types, Ambient_operators, Cache ) -> fun(Value, Positions, Memo) -> case Value of {closure, Params, Body} -> {Operator, Memo@1} = analyze_closure( Params, Body, Positions, Context, Function_map, Knowledge_base, Visited, Registry, Module_types, Ambient_operators, Cache, Memo ), {{ok, Operator}, Memo@1}; {local_ref, Name} -> case {gleam@set:contains(Visited, Name), gleam_stdlib:map_get(Function_map, Name)} of {false, {ok, Definition}} -> {Operator@1, Memo@2} = lift_local_function( Name, Definition, Context, Function_map, Knowledge_base, Visited, Registry, Module_types, Cache, Memo ), {{ok, Operator@1}, Memo@2}; {_, _} -> {{error, nil}, Memo} end; {returned_operator, Callee, Args} -> resolve_returned_operator( Callee, Args, Context, Function_map, Knowledge_base, Visited, Registry, Module_types, Cache, Memo ); _ -> {{error, nil}, Memo} end end. -file("src/graded/internal/checker.gleam", 1688). ?DOC(false). -spec bind_producer_params( graded@internal@types:effect_term(), graded@internal@types:qualified_name(), list(graded@internal@types:call_argument()), graded@internal@extract:import_context(), gleam@dict:dict(binary(), glance:definition(glance:function_())), graded@internal@effects:knowledge_base(), gleam@set:set(binary()), graded@internal@signatures:signature_registry(), gleam@dict:dict({integer(), integer()}, girard@types:type()), local_cache(), memo() ) -> {graded@internal@types:effect_term(), memo()}. bind_producer_params( Operator, Callee, Args, Context, Function_map, Knowledge_base, Visited, Registry, Module_types, Cache, Memo ) -> {Bounds@1, Effective_registry} = case erlang:element(2, Callee) of <<""/utf8>> -> case gleam_stdlib:map_get(Function_map, erlang:element(3, Callee)) of {ok, Definition} -> Local_registry = graded@internal@signatures:from_glance_module( <<""/utf8>>, {module, [], [], [], [], [Definition]} ), Bounds = begin _pipe = erlang:element(3, Definition), _pipe@1 = ordered_fn_typed_param_names(_pipe), gleam@list:map(_pipe@1, fun self_referential_bound/1) end, {Bounds, graded@internal@signatures:merge( Registry, Local_registry )}; {error, nil} -> {[], Registry} end; _ -> {graded@internal@effects:lookup_param_bounds(Knowledge_base, Callee), Registry} end, Lift = build_lift_operator_arg( Context, Function_map, Knowledge_base, Visited, Registry, Module_types, maps:new(), Cache ), {Bindings, Memo@1} = bind_variables( Callee, Bounds@1, Args, Knowledge_base, [], Effective_registry, Lift, Memo ), {graded@internal@effect_term:normalize( graded@internal@effect_term:subst(Operator, Bindings) ), Memo@1}. -file("src/graded/internal/checker.gleam", 1765). ?DOC(false). -spec compute_returned_operator( glance:function_(), graded@internal@extract:import_context(), gleam@dict:dict(binary(), glance:definition(glance:function_())), graded@internal@effects:knowledge_base(), gleam@set:set(binary()), graded@internal@signatures:signature_registry(), gleam@dict:dict({integer(), integer()}, girard@types:type()), local_cache(), memo() ) -> {{ok, graded@internal@types:effect_term()} | {error, nil}, memo()}. compute_returned_operator( Function, Context, Function_map, Knowledge_base, Visited, Registry, Module_types, Cache, Memo ) -> Gated = begin gleam@result:'try'( gleam@option:to_result(erlang:element(6, Function), nil), fun(Return_type) -> gleam@bool:guard( not graded@internal@signatures:is_function_return_type( Return_type ), {error, nil}, fun() -> gleam@result:'try'( graded@internal@extract:return_value( Function, Context ), fun(Value) -> {ok, {Return_type, Value}} end ) end ) end ) end, case Gated of {error, nil} -> {{error, nil}, Memo}; {ok, {Return_type@1, Value@1}} -> Positions = graded@internal@signatures:operator_callback_positions_of_type( Return_type@1 ), Producer_operators = graded@internal@signatures:operator_params_from_function( Function ), Producer_bounds = begin _pipe = Function, _pipe@1 = ordered_fn_typed_param_names(_pipe), gleam@list:map(_pipe@1, fun self_referential_bound/1) end, Lift = build_lift_operator_arg( Context, Function_map, Knowledge_base, Visited, Registry, Module_types, Producer_operators, Cache ), {Operator, Memo@1} = operator_term_for_argument( {call_argument, 0, none, Value@1}, Positions, Knowledge_base, Producer_bounds, Registry, Lift, Memo ), {compute_returned_operator_result(Operator), Memo@1} end. -file("src/graded/internal/checker.gleam", 1621). ?DOC(false). -spec resolve_returned_operator( graded@internal@types:qualified_name(), list(graded@internal@types:call_argument()), graded@internal@extract:import_context(), gleam@dict:dict(binary(), glance:definition(glance:function_())), graded@internal@effects:knowledge_base(), gleam@set:set(binary()), graded@internal@signatures:signature_registry(), gleam@dict:dict({integer(), integer()}, girard@types:type()), local_cache(), memo() ) -> {{ok, graded@internal@types:effect_term()} | {error, nil}, memo()}. resolve_returned_operator( Callee, Args, Context, Function_map, Knowledge_base, Visited, Registry, Module_types, Cache, Memo ) -> {Lookup, Memo@1} = case erlang:element(2, Callee) of <<""/utf8>> -> case {gleam@set:contains(Visited, erlang:element(3, Callee)), gleam_stdlib:map_get(Function_map, erlang:element(3, Callee))} of {false, {ok, Definition}} -> compute_returned_operator( erlang:element(3, Definition), Context, Function_map, Knowledge_base, gleam@set:insert(Visited, erlang:element(3, Callee)), Registry, Module_types, Cache, Memo ); {_, _} -> {{error, nil}, Memo} end; _ -> {graded@internal@effects:lookup_returned_operator( Knowledge_base, Callee ), Memo} end, case Lookup of {error, nil} -> {{error, nil}, Memo@1}; {ok, Operator} -> case gleam@set:is_empty( graded@internal@effect_term:free_vars(Operator) ) of true -> {{ok, Operator}, Memo@1}; false -> {Bound, Memo@2} = bind_producer_params( Operator, Callee, Args, Context, Function_map, Knowledge_base, Visited, Registry, Module_types, Cache, Memo@1 ), {{ok, Bound}, Memo@2} end end. -file("src/graded/internal/checker.gleam", 2291). ?DOC(false). -spec memoized_local( graded@internal@types:local_call(), glance:definition(glance:function_()), gleam@set:set(binary()), gleam@dict:dict(binary(), glance:definition(glance:function_())), graded@internal@extract:import_context(), graded@internal@effects:knowledge_base(), graded@internal@signatures:signature_registry(), gleam@dict:dict({integer(), integer()}, girard@types:type()), local_cache(), memo() ) -> {list({graded@internal@types:resolved_call(), graded@internal@types:effect_term()}), memo()}. memoized_local( Local_call, Local_definition, Visited, Function_map, Context, Knowledge_base, Registry, Module_types, Cache, Memo ) -> Scc = begin _pipe = gleam_stdlib:map_get( erlang:element(2, Cache), erlang:element(2, Local_call) ), gleam@result:unwrap(_pipe, -1) end, case gleam@set:contains(erlang:element(4, Cache), Scc) of true -> collapsed_scc( Scc, Function_map, Context, Knowledge_base, Registry, Module_types, Cache, Memo ); false -> Nested_bounds = synthetic_fn_typed_bounds( graded@internal@signatures:fn_typed_params_from_function( erlang:element(3, Local_definition) ) ), Key = memo_key(erlang:element(2, Local_call), Visited, Cache), case gleam_stdlib:map_get(erlang:element(2, Memo), Key) of {ok, Cached} -> {Cached, Memo}; {error, nil} -> New_visited = gleam@set:insert( Visited, erlang:element(2, Local_call) ), {Result, Memo@1} = collect_effects( without_returned_closure( erlang:element(3, Local_definition) ), Function_map, Context, Knowledge_base, New_visited, Nested_bounds, Registry, Module_types, maps:new(), Cache, Memo ), {Result, {memo, gleam@dict:insert( erlang:element(2, Memo@1), Key, Result ), erlang:element(3, Memo@1), erlang:element(4, Memo@1), erlang:element(5, Memo@1)}} end end. -file("src/graded/internal/checker.gleam", 2211). ?DOC(false). -spec resolve_unknown_local( graded@internal@types:local_call(), gleam@set:set(binary()), gleam@dict:dict(binary(), glance:definition(glance:function_())), graded@internal@extract:import_context(), graded@internal@effects:knowledge_base(), graded@internal@signatures:signature_registry(), gleam@dict:dict({integer(), integer()}, girard@types:type()), local_cache(), memo() ) -> {list({graded@internal@types:resolved_call(), graded@internal@types:effect_term()}), memo()}. resolve_unknown_local( Local_call, Visited, Function_map, Context, Knowledge_base, Registry, Module_types, Cache, Memo ) -> gleam@bool:guard( gleam@set:contains(Visited, erlang:element(2, Local_call)), {[], Memo}, fun() -> case gleam_stdlib:map_get( Function_map, erlang:element(2, Local_call) ) of {error, nil} -> Synthetic_call = {resolved_call, {qualified_name, <<""/utf8>>, erlang:element(2, Local_call)}, erlang:element(3, Local_call)}, {[{Synthetic_call, graded@internal@effect_term:unknown()}], Memo}; {ok, Local_definition} -> case is_opaque_external(Local_definition) of true -> {[{{resolved_call, {qualified_name, <<""/utf8>>, erlang:element(2, Local_call)}, erlang:element(3, Local_call)}, graded@internal@effect_term:unknown()}], Memo}; false -> memoized_local( Local_call, Local_definition, Visited, Function_map, Context, Knowledge_base, Registry, Module_types, Cache, Memo ) end end end ). -file("src/graded/internal/checker.gleam", 845). ?DOC(false). -spec collect_effects( glance:function_(), gleam@dict:dict(binary(), glance:definition(glance:function_())), graded@internal@extract:import_context(), graded@internal@effects:knowledge_base(), gleam@set:set(binary()), list(graded@internal@types:param_bound()), graded@internal@signatures:signature_registry(), gleam@dict:dict({integer(), integer()}, girard@types:type()), gleam@dict:dict(binary(), list(integer())), local_cache(), memo() ) -> {list({graded@internal@types:resolved_call(), graded@internal@types:effect_term()}), memo()}. collect_effects( Function, Function_map, Context, Knowledge_base, Visited, Param_bounds, Registry, Module_types, Ambient_operators, Cache, Memo ) -> Result = graded@internal@extract:extract_calls( erlang:element(7, Function), Context ), Operator_params = maps:merge( Ambient_operators, graded@internal@signatures:operator_params_from_function(Function) ), Lift_operator_arg = build_lift_operator_arg( Context, Function_map, Knowledge_base, Visited, Registry, Module_types, Ambient_operators, Cache ), {Memo@3, Resolved_effects} = gleam@list:map_fold( erlang:element(2, Result), Memo, fun(Memo@1, Call) -> Effect_set = graded@internal@effects:lookup_effects( Knowledge_base, erlang:element(2, Call) ), {Concrete, Memo@2} = substitute_at_call_site( Call, Effect_set, erlang:element(8, Result), Knowledge_base, Param_bounds, Registry, Lift_operator_arg, Memo@1 ), {Memo@2, {Call, Concrete}} end ), {Memo@6, Local_effects_nested} = gleam@list:map_fold( erlang:element(3, Result), Memo@3, fun(Memo@4, Local_call) -> case gleam@list:find( Param_bounds, fun(Param) -> erlang:element(2, Param) =:= erlang:element(2, Local_call) end ) of {ok, Bound} -> Synthetic_call = {resolved_call, {qualified_name, <<""/utf8>>, erlang:element(2, Local_call)}, erlang:element(3, Local_call)}, Effect = case gleam_stdlib:map_get( Operator_params, erlang:element(2, Local_call) ) of {error, nil} -> erlang:element(3, Bound); {ok, Positions} -> curried_operator_application( erlang:element(3, Bound), Positions, erlang:element(8, Result), erlang:element(2, erlang:element(3, Local_call)), Knowledge_base, Param_bounds ) end, {Memo@4, [{Synthetic_call, Effect}]}; {error, nil} -> {Recursive, Memo@5} = resolve_unknown_local( Local_call, Visited, Function_map, Context, Knowledge_base, Registry, Module_types, Cache, Memo@4 ), _pipe = substitute_local_call_effects( Recursive, Local_call, erlang:element(8, Result), Function_map, Knowledge_base, Param_bounds, Registry, Lift_operator_arg, Memo@5 ), (fun(Pair) -> {erlang:element(2, Pair), erlang:element(1, Pair)} end)(_pipe) end end ), Local_effects = lists:append(Local_effects_nested), {Memo@9, Field_effects} = gleam@list:map_fold( erlang:element(4, Result), Memo@6, fun(Memo@7, Field_call) -> Synthetic_call@1 = {resolved_call, {qualified_name, <<""/utf8>>, <<<<(erlang:element(2, Field_call))/binary, "."/utf8>>/binary, (erlang:element(3, Field_call))/binary>>}, erlang:element(4, Field_call)}, {Effect_set@1, Memo@8} = resolve_field_call( Field_call, Function, Knowledge_base, Module_types, erlang:element(8, Result), Param_bounds, Registry, Lift_operator_arg, Memo@7 ), {Memo@8, {Synthetic_call@1, Effect_set@1}} end ), {Memo@12, Direct_op_effects} = gleam@list:map_fold( erlang:element(6, Result), Memo@9, fun(Memo@10, Op) -> Synthetic_call@2 = {resolved_call, {qualified_name, <<""/utf8>>, erlang:element(3, erlang:element(2, Op))}, erlang:element(4, Op)}, {Resolved_op, Memo@11} = resolve_returned_operator( erlang:element(2, Op), erlang:element(3, Op), Context, Function_map, Knowledge_base, Visited, Registry, Module_types, Cache, Memo@10 ), Effect@1 = case Resolved_op of {ok, Operator} -> Positions@1 = positions_up_to( operator_spine_arity(Operator) ), curried_operator_application( Operator, Positions@1, erlang:element(8, Result), erlang:element(2, erlang:element(4, Op)), Knowledge_base, Param_bounds ); {error, nil} -> graded@internal@effect_term:unknown() end, {Memo@11, {Synthetic_call@2, Effect@1}} end ), {Memo@15, Direct_pipe_effects} = gleam@list:map_fold( erlang:element(7, Result), Memo@12, fun(Memo@13, Op@1) -> Synthetic_call@3 = {resolved_call, {qualified_name, <<""/utf8>>, <<""/utf8>>}, erlang:element(3, Op@1)}, {Operator@1, Memo@14} = operator_term_for_argument( {call_argument, 0, none, erlang:element(2, Op@1)}, [0], Knowledge_base, Param_bounds, Registry, Lift_operator_arg, Memo@13 ), Effect@2 = curried_operator_application( Operator@1, [0], erlang:element(8, Result), erlang:element(2, erlang:element(3, Op@1)), Knowledge_base, Param_bounds ), {Memo@14, {Synthetic_call@3, Effect@2}} end ), {lists:append( [Resolved_effects, Local_effects, Field_effects, Direct_op_effects, Direct_pipe_effects] ), Memo@15}. -file("src/graded/internal/checker.gleam", 684). ?DOC(false). -spec check_annotation( graded@internal@types:effect_annotation(), gleam@dict:dict(binary(), glance:definition(glance:function_())), graded@internal@extract:import_context(), graded@internal@effects:knowledge_base(), graded@internal@signatures:signature_registry(), gleam@dict:dict({integer(), integer()}, girard@types:type()), local_cache(), memo() ) -> {{list(graded@internal@types:violation()), list(graded@internal@types:warning())}, memo()}. check_annotation( Annotation, Function_map, Context, Knowledge_base, Registry, Module_types, Cache, Memo ) -> case gleam_stdlib:map_get(Function_map, erlang:element(3, Annotation)) of {error, nil} -> {{[], []}, Memo}; {ok, Function_definition} -> {Body_effects, Memo@1} = collect_effects( without_returned_closure(erlang:element(3, Function_definition)), Function_map, Context, Knowledge_base, gleam@set:new(), erlang:element(4, Annotation), Registry, Module_types, maps:new(), Cache, Memo ), Declared = graded@internal@effect_term:to_effect_set( erlang:element(5, Annotation) ), Violations = begin _pipe = Body_effects, gleam@list:filter_map( _pipe, fun(Pair) -> {Call, Call_term} = Pair, Actual = graded@internal@effect_term:to_effect_set( Call_term ), case graded@internal@types:is_subset(Actual, Declared) of true -> {error, nil}; false -> {ok, {violation, erlang:element(3, Annotation), erlang:element(2, Call), erlang:element(3, Call), Declared, Actual}} end end ) end, Extract_result = graded@internal@extract:extract_calls( erlang:element(7, erlang:element(3, Function_definition)), Context ), Reference_warnings = collect_reference_warnings( erlang:element(3, Annotation), erlang:element(5, Extract_result), Knowledge_base ), Param_names = begin _pipe@1 = erlang:element( 5, erlang:element(3, Function_definition) ), _pipe@2 = gleam@list:filter_map( _pipe@1, fun(Param) -> case erlang:element(3, Param) of {named, Name} -> {ok, Name}; {discarded, _} -> {error, nil} end end ), gleam@set:from_list(_pipe@2) end, Field_call_targets = begin _pipe@3 = erlang:element(4, Extract_result), _pipe@4 = gleam@list:map( _pipe@3, fun(Field_call) -> <<<<(erlang:element(2, Field_call))/binary, "."/utf8>>/binary, (erlang:element(3, Field_call))/binary>> end ), gleam@set:from_list(_pipe@4) end, Unmatched_field_bound_warnings = begin _pipe@5 = erlang:element(4, Annotation), _pipe@6 = gleam@list:filter( _pipe@5, fun(Bound) -> gleam_stdlib:contains_string( erlang:element(2, Bound), <<"."/utf8>> ) end ), _pipe@7 = gleam@list:filter( _pipe@6, fun(Bound@1) -> not gleam@set:contains( Field_call_targets, erlang:element(2, Bound@1) ) end ), gleam@list:map( _pipe@7, fun(Bound@2) -> Receiver@1 = case gleam@string:split_once( erlang:element(2, Bound@2), <<"."/utf8>> ) of {ok, {Receiver, _}} -> Receiver; {error, nil} -> erlang:element(2, Bound@2) end, {unmatched_field_bound_warning, erlang:element(3, Annotation), erlang:element(2, Bound@2), gleam@set:contains(Param_names, Receiver@1)} end ) end, Unmatched_param_bound_warnings = begin _pipe@8 = erlang:element(4, Annotation), _pipe@9 = gleam@list:filter( _pipe@8, fun(Bound@3) -> not gleam_stdlib:contains_string( erlang:element(2, Bound@3), <<"."/utf8>> ) end ), _pipe@10 = gleam@list:filter( _pipe@9, fun(Bound@4) -> not gleam@set:contains( Param_names, erlang:element(2, Bound@4) ) end ), gleam@list:map( _pipe@10, fun(Bound@5) -> {unmatched_param_bound_warning, erlang:element(3, Annotation), erlang:element(2, Bound@5)} end ) end, Warnings = begin _pipe@11 = Reference_warnings, _pipe@12 = lists:append( _pipe@11, Unmatched_field_bound_warnings ), lists:append(_pipe@12, Unmatched_param_bound_warnings) end, {{Violations, Warnings}, Memo@1} end. -file("src/graded/internal/checker.gleam", 578). ?DOC(false). -spec new_memo() -> memo(). new_memo() -> {memo, maps:new(), maps:new(), maps:new(), maps:new()}. -file("src/graded/internal/checker.gleam", 603). ?DOC(false). -spec recursion_edges( glance:function_(), graded@internal@extract:import_context(), gleam@set:set(binary()) ) -> gleam@set:set(binary()). recursion_edges(Function, Context, Names) -> Result = graded@internal@extract:extract_calls( erlang:element(7, Function), Context ), Local = gleam@list:map( erlang:element(3, Result), fun(Call) -> erlang:element(2, Call) end ), Returned = gleam@list:filter_map( erlang:element(6, Result), fun(Op) -> case erlang:element(2, erlang:element(2, Op)) of <<""/utf8>> -> {ok, erlang:element(3, erlang:element(2, Op))}; _ -> {error, nil} end end ), Lifted = begin _pipe = erlang:element(8, Result), _pipe@1 = maps:values(_pipe), _pipe@2 = lists:append(_pipe@1), gleam@list:filter_map( _pipe@2, fun(Argument) -> case erlang:element(4, Argument) of {local_ref, Name} -> {ok, Name}; _ -> {error, nil} end end ) end, _pipe@3 = lists:append([Local, Returned, Lifted]), _pipe@4 = gleam@set:from_list(_pipe@3), gleam@set:intersection(_pipe@4, Names). -file("src/graded/internal/checker.gleam", 515). ?DOC(false). -spec local_call_graph( list(glance:definition(glance:function_())), graded@internal@extract:import_context() ) -> gleam@dict:dict(binary(), gleam@set:set(binary())). local_call_graph(Definitions, Context) -> Names = begin _pipe = Definitions, _pipe@1 = gleam@list:map( _pipe, fun(Definition) -> erlang:element(3, erlang:element(3, Definition)) end ), gleam@set:from_list(_pipe@1) end, gleam@list:fold( Definitions, maps:new(), fun(Graph, Definition@1) -> Edges = recursion_edges( erlang:element(3, Definition@1), Context, Names ), gleam@dict:insert( Graph, erlang:element(3, erlang:element(3, Definition@1)), Edges ) end ). -file("src/graded/internal/checker.gleam", 488). ?DOC(false). -spec alias_fn_typed_params(glance:function_(), gleam@set:set(binary())) -> gleam@set:set(binary()). alias_fn_typed_params(Function, Fn_aliases) -> _pipe = gleam@list:filter_map( erlang:element(5, Function), fun(Parameter) -> case {erlang:element(3, Parameter), erlang:element(4, Parameter)} of {{named, Name}, {some, {named_type, _, Type_name, none, _}}} -> case gleam@set:contains(Fn_aliases, Type_name) of true -> {ok, Name}; false -> {error, nil} end; {_, _} -> {error, nil} end end ), gleam@set:from_list(_pipe). -file("src/graded/internal/checker.gleam", 463). ?DOC(false). -spec resolves_to_function( glance:type(), gleam@dict:dict(binary(), glance:type()), gleam@set:set(binary()) ) -> boolean(). resolves_to_function(Type_, Alias_map, Seen) -> case Type_ of {function_type, _, _, _} -> true; {named_type, _, Name, none, _} -> case gleam@set:contains(Seen, Name) of true -> false; false -> case gleam_stdlib:map_get(Alias_map, Name) of {ok, Aliased} -> resolves_to_function( Aliased, Alias_map, gleam@set:insert(Seen, Name) ); {error, nil} -> false end end; _ -> false end. -file("src/graded/internal/checker.gleam", 434). ?DOC(false). -spec function_type_aliases(list(glance:definition(glance:type_alias()))) -> gleam@set:set(binary()). function_type_aliases(Aliases) -> Alias_map = gleam@list:fold( Aliases, maps:new(), fun(Acc, Definition) -> gleam@dict:insert( Acc, erlang:element(3, erlang:element(3, Definition)), erlang:element(6, erlang:element(3, Definition)) ) end ), _pipe = gleam@list:filter_map( maps:keys(Alias_map), fun(Name) -> case resolves_to_function( {named_type, {span, 0, 0}, Name, none, []}, Alias_map, gleam@set:new() ) of true -> {ok, Name}; false -> {error, nil} end end ), gleam@set:from_list(_pipe). -file("src/graded/internal/checker.gleam", 376). ?DOC(false). -spec build_scc_ids( glance:module_(), graded@internal@extract:import_context(), gleam@dict:dict(binary(), gleam@set:set(binary())), boolean() ) -> local_cache(). build_scc_ids(Module, Context, Girard_fn_typed, Collapse) -> Definitions = erlang:element(6, Module), Fn_aliases = function_type_aliases(erlang:element(4, Module)), Needs_exact = begin _pipe@3 = gleam@list:filter_map( Definitions, fun(Definition) -> Name = erlang:element(3, erlang:element(3, Definition)), First_order = begin _pipe = graded@internal@signatures:fn_typed_params_from_function( erlang:element(3, Definition) ), _pipe@1 = gleam@set:union( _pipe, alias_fn_typed_params( erlang:element(3, Definition), Fn_aliases ) ), _pipe@2 = gleam@set:union( _pipe@1, graded@internal@typeinfo:fn_typed_params( Girard_fn_typed, Name ) ), gleam@set:is_empty(_pipe@2) end, case First_order andalso not is_opaque_external(Definition) of true -> {error, nil}; false -> {ok, Name} end end ), gleam@set:from_list(_pipe@3) end, _pipe@4 = graded@internal@topo:scc_order( local_call_graph(Definitions, Context) ), gleam@list:index_fold( _pipe@4, {local_cache, maps:new(), maps:new(), gleam@set:new()}, fun(Cache, Component, Id) -> Scc_id = gleam@list:fold( Component, erlang:element(2, Cache), fun(Ids, Name@1) -> gleam@dict:insert(Ids, Name@1, Id) end ), Collapsible = case Collapse andalso not gleam@list:any( Component, fun(Name@2) -> gleam@set:contains(Needs_exact, Name@2) end ) of true -> gleam@set:insert(erlang:element(4, Cache), Id); false -> erlang:element(4, Cache) end, {local_cache, Scc_id, gleam@dict:insert(erlang:element(3, Cache), Id, Component), Collapsible} end ). -file("src/graded/internal/checker.gleam", 328). ?DOC(false). -spec build_function_map(glance:module_()) -> gleam@dict:dict(binary(), glance:definition(glance:function_())). build_function_map(Module) -> _pipe = erlang:element(6, Module), _pipe@1 = gleam@list:map( _pipe, fun(Definition) -> {erlang:element(3, erlang:element(3, Definition)), Definition} end ), maps:from_list(_pipe@1). -file("src/graded/internal/checker.gleam", 28). ?DOC(false). -spec check( glance:module_(), list(graded@internal@types:effect_annotation()), graded@internal@effects:knowledge_base(), graded@internal@signatures:signature_registry(), gleam@dict:dict({integer(), integer()}, girard@types:type()), gleam@dict:dict(binary(), gleam@set:set(binary())) ) -> {list(graded@internal@types:violation()), list(graded@internal@types:warning())}. check( Module, Annotations, Knowledge_base, Registry, Module_types, Girard_fn_typed ) -> Context = begin _pipe = graded@internal@extract:build_import_context(Module), _pipe@1 = graded@internal@extract:with_factories( _pipe, graded@internal@extract:factory_map(Module) ), graded@internal@extract:with_cross_factories( _pipe@1, graded@internal@effects:factories(Knowledge_base) ) end, Function_map = build_function_map(Module), Cache = build_scc_ids(Module, Context, Girard_fn_typed, true), {_, Results} = gleam@list:map_fold( Annotations, new_memo(), fun(Memo, Annotation) -> {Result, Memo@1} = check_annotation( Annotation, Function_map, Context, Knowledge_base, Registry, Module_types, Cache, Memo ), {Memo@1, Result} end ), Violations = gleam@list:flat_map( Results, fun(R) -> erlang:element(1, R) end ), Warnings = gleam@list:flat_map( Results, fun(R@1) -> erlang:element(2, R@1) end ), {Violations, Warnings}. -file("src/graded/internal/checker.gleam", 297). ?DOC(false). -spec polymorphic_param_bounds( graded@internal@types:effect_term(), gleam@set:set(binary()) ) -> list(graded@internal@types:param_bound()). polymorphic_param_bounds(Term, Fn_typed_params) -> _pipe = Term, _pipe@1 = graded@internal@effect_term:free_vars(_pipe), _pipe@2 = gleam@set:to_list(_pipe@1), _pipe@3 = gleam@list:filter( _pipe@2, fun(V) -> gleam@set:contains(Fn_typed_params, V) end ), _pipe@4 = gleam@list:sort(_pipe@3, fun gleam@string:compare/2), gleam@list:map(_pipe@4, fun self_referential_bound/1). -file("src/graded/internal/checker.gleam", 89). ?DOC(false). -spec infer_with_returns( glance:module_(), graded@internal@effects:knowledge_base(), list(graded@internal@types:effect_annotation()), graded@internal@signatures:signature_registry(), gleam@dict:dict({integer(), integer()}, girard@types:type()), gleam@dict:dict(binary(), gleam@set:set(binary())) ) -> {list(graded@internal@types:effect_annotation()), gleam@dict:dict(binary(), graded@internal@types:effect_term())}. infer_with_returns( Module, Knowledge_base, Existing_checks, Registry, Module_types, Girard_fn_typed ) -> Context = begin _pipe = graded@internal@extract:build_import_context(Module), _pipe@1 = graded@internal@extract:with_factories( _pipe, graded@internal@extract:factory_map(Module) ), graded@internal@extract:with_cross_factories( _pipe@1, graded@internal@effects:factories(Knowledge_base) ) end, Function_map = build_function_map(Module), Cache = build_scc_ids(Module, Context, Girard_fn_typed, true), Public_functions = gleam@list:filter( erlang:element(6, Module), fun(Definition) -> erlang:element(4, erlang:element(3, Definition)) =:= public end ), {Memo@2, Returned_pairs} = gleam@list:map_fold( Public_functions, new_memo(), fun(Memo, Definition@1) -> {Returned, Memo@1} = compute_returned_operator( erlang:element(3, Definition@1), Context, Function_map, Knowledge_base, gleam@set:new(), Registry, Module_types, Cache, Memo ), {Memo@1, gleam@result:map( Returned, fun(Operator) -> {erlang:element(3, erlang:element(3, Definition@1)), Operator} end )} end ), Returned_operators = begin _pipe@2 = Returned_pairs, _pipe@3 = gleam@list:filter_map(_pipe@2, fun(Pair) -> Pair end), maps:from_list(_pipe@3) end, Bounds_map = begin _pipe@4 = Existing_checks, _pipe@5 = gleam@list:filter( _pipe@4, fun(Annotation) -> erlang:element(4, Annotation) /= [] end ), _pipe@6 = gleam@list:map( _pipe@5, fun(Annotation@1) -> {erlang:element(3, Annotation@1), erlang:element(4, Annotation@1)} end ), maps:from_list(_pipe@6) end, {_, Annotations} = gleam@list:map_fold( Public_functions, Memo@2, fun(Memo@3, Definition@2) -> Param_bounds = begin _pipe@7 = gleam_stdlib:map_get( Bounds_map, erlang:element(3, erlang:element(3, Definition@2)) ), gleam@result:unwrap(_pipe@7, []) end, Declared_bound_names = begin _pipe@8 = Param_bounds, _pipe@9 = gleam@list:map( _pipe@8, fun(B) -> erlang:element(2, B) end ), gleam@set:from_list(_pipe@9) end, Fn_typed_params = begin _pipe@10 = graded@internal@signatures:fn_typed_params_from_function( erlang:element(3, Definition@2) ), _pipe@11 = gleam@set:union( _pipe@10, graded@internal@typeinfo:fn_typed_params( Girard_fn_typed, erlang:element(3, erlang:element(3, Definition@2)) ) ), gleam@set:filter( _pipe@11, fun(Name) -> not gleam@set:contains(Declared_bound_names, Name) end ) end, Effective_bounds = lists:append( Param_bounds, synthetic_fn_typed_bounds(Fn_typed_params) ), {Effects_term, Memo@5} = case is_opaque_external(Definition@2) of true -> {graded@internal@effect_term:unknown(), Memo@3}; false -> {Pairs, Memo@4} = collect_effects( without_returned_closure( erlang:element(3, Definition@2) ), Function_map, Context, Knowledge_base, gleam@set:new(), Effective_bounds, Registry, Module_types, maps:new(), Cache, Memo@3 ), {union_of(Pairs), Memo@4} end, Inferred_params = polymorphic_param_bounds( Effects_term, Fn_typed_params ), {Memo@5, {effect_annotation, effects, erlang:element(3, erlang:element(3, Definition@2)), Inferred_params, Effects_term}} end ), {Annotations, Returned_operators}. -file("src/graded/internal/checker.gleam", 67). ?DOC(false). -spec infer( glance:module_(), graded@internal@effects:knowledge_base(), list(graded@internal@types:effect_annotation()), graded@internal@signatures:signature_registry(), gleam@dict:dict({integer(), integer()}, girard@types:type()), gleam@dict:dict(binary(), gleam@set:set(binary())) ) -> list(graded@internal@types:effect_annotation()). infer( Module, Knowledge_base, Existing_checks, Registry, Module_types, Girard_fn_typed ) -> erlang:element( 1, infer_with_returns( Module, Knowledge_base, Existing_checks, Registry, Module_types, Girard_fn_typed ) ). -file("src/graded/internal/checker.gleam", 652). ?DOC(false). -spec closure_field_operator( list(binary()), list(glance:statement()), graded@internal@extract:import_context(), gleam@dict:dict(binary(), glance:definition(glance:function_())), graded@internal@effects:knowledge_base(), local_cache() ) -> graded@internal@types:effect_term(). closure_field_operator( Params, Body, Context, Function_map, Knowledge_base, Scc_ids ) -> Positions = gleam@list:index_map(Params, fun(_, Index) -> Index end), erlang:element( 1, analyze_closure( Params, Body, Positions, Context, Function_map, Knowledge_base, gleam@set:new(), graded@internal@signatures:empty(), maps:new(), maps:new(), Scc_ids, new_memo() ) ).