Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file helpers.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195open!Baseopen!PpxlibopenAst_builder.Defaultlet(-->)lhsrhs=case~guard:None~lhs~rhs(* Utility functions *)letreplace_variables_by_underscores=letmap=objectinheritAst_traverse.mapassupermethod!core_type_desc=function|Ptyp_var_->Ptyp_any|t->super#core_type_desctendinmap#core_type;;letmake_rigid_typestps=List.foldtps~init:(Map.empty(moduleString))~f:(funmaptp->Map.updatemaptp.txt~f:(function|None->Fresh_name.of_string_loctp|Somefresh->(* Ignore duplicate names, the typechecker will raise after expansion. *)fresh));;letfind_rigid_type~loc~rigid_typesname=matchMap.findrigid_typesnamewith|Sometp->Fresh_name.to_string_loctp|None->(* Ignore unbound type names, the typechecker will raise after expansion. *){txt=name;loc};;letmake_type_rigid~rigid_types=letmap=objectinheritAst_traverse.mapassupermethod!core_typety=letptyp_desc=matchty.ptyp_descwith|Ptyp_vars->Ptyp_constr(Located.map_lident(find_rigid_type~loc:ty.ptyp_loc~rigid_typess),[])|desc->super#core_type_descdescin{tywithptyp_desc}endinmap#core_type;;(* Generates the quantified type [ ! 'a .. 'z . (make_mono_type t ('a .. 'z)) ] or
[type a .. z. make_mono_type t (a .. z)] when [use_rigid_variables] is true.
Annotation are needed for non regular recursive datatypes and gadt when the return type
of constructors are constrained. Unfortunately, putting rigid variables everywhere does
not work because of certains types with constraints. We thus only use rigid variables
for sum types, which includes all GADTs. *)lettvars_of_core_type:core_type->stringlist=lettvars=objectinherit[stringlist]Ast_traverse.foldassupermethod!core_typexacc=matchx.ptyp_descwith|Ptyp_varx->ifList.memaccx~equal:String.equalthenaccelsex::acc|_->super#core_typexaccendinfuntyp->List.rev(tvars#core_typetyp[]);;letconstrained_function_binding(* placing a suitably polymorphic or rigid type constraint on the pattern or body *)(loc:Location.t)(td:type_declaration)(typ:core_type)~(tps:stringloclist)~(func_name:string)(body:expression)=letvars=tvars_of_core_typetypinlethas_vars=matchvarswith|[]->false|_::_->trueinletpat=letpat=pvar~locfunc_nameinifnothas_varsthenpatelse(letvars=List.map~f:(funtxt->{txt;loc})varsinppat_constraint~locpat(ptyp_poly~locvarstyp))inletbody=letuse_rigid_variables=matchtd.ptype_kindwith|Ptype_variant_->true|_->falseinifuse_rigid_variablesthen(letrigid_types=make_rigid_typestpsinList.fold_righttps~f:(funtpbody->pexp_newtype~loc(find_rigid_type~loc:tp.loc~rigid_typestp.txt)body)~init:(pexp_constraint~locbody(make_type_rigid~rigid_typestyp)))elseifhas_varsthenbodyelsepexp_constraint~locbodytypinvalue_binding~loc~pat~expr:body;;letwith_let~loc~bindsbody=List.fold_rightbinds~init:body~f:(pexp_let~locNonrecursive);;letfresh_lambda~locapply=letvar=gen_symbol~prefix:"x"()inletpat=pvar~locvarinletarg=evar~locvarinletbody=apply~arginpexp_fun~locNolabelNonepatbody;;letrecis_value_expressionexpr=matchexpr.pexp_descwith(* Syntactic values. *)|Pexp_ident_|Pexp_constant_|Pexp_function_|Pexp_fun_|Pexp_lazy_->true(* Type-only wrappers; we check their contents. *)|Pexp_constraint(expr,(_:core_type))|Pexp_coerce(expr,(_:core_typeoption),(_:core_type))|Pexp_newtype((_:stringloc),expr)->is_value_expressionexpr(* Allocating constructors; they are only values if all of their contents are. *)|Pexp_tupleexprs->List.for_allexprs~f:is_value_expression|Pexp_construct(_,maybe_expr)->Option.for_allmaybe_expr~f:is_value_expression|Pexp_variant(_,maybe_expr)->Option.for_allmaybe_expr~f:is_value_expression|Pexp_record(fields,maybe_expr)->List.for_allfields~f:(fun(_,expr)->is_value_expressionexpr)&&Option.for_allmaybe_expr~f:is_value_expression(* Not values, or not always values. We make a conservative approximation. *)|Pexp_unreachable|Pexp_let_|Pexp_apply_|Pexp_match_|Pexp_try_|Pexp_field_|Pexp_setfield_|Pexp_array_|Pexp_ifthenelse_|Pexp_sequence_|Pexp_while_|Pexp_for_|Pexp_send_|Pexp_new_|Pexp_setinstvar_|Pexp_override_|Pexp_letmodule_|Pexp_letexception_|Pexp_assert_|Pexp_poly_|Pexp_object_|Pexp_pack_|Pexp_open_|Pexp_letop_|Pexp_extension_->false;;letreally_recursive_respecting_opaquerec_flagtds=(objectinherittype_is_recursiverec_flagtdsassupermethod!core_typectype=matchctypewith|_whenOption.is_some(Attribute.get~mark_as_seen:falseAttrs.opaquectype)->()|[%type:[%t?_]sexp_opaque]->()|_->super#core_typectypeend)#go();;