123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921(**************************************************************************)(* *)(* OCaml *)(* *)(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *)(* *)(* Copyright 1996 Institut National de Recherche en Informatique et *)(* en Automatique. *)(* *)(* All rights reserved. This file is distributed under the terms of *)(* the GNU Lesser General Public License version 2.1, with the *)(* special exception on linking described in the file LICENSE. *)(* *)(**************************************************************************)(* Representation of types and declarations *)openAsttypes(* Type expressions for the core language *)typetransient_expr={mutabledesc:type_desc;mutablelevel:int;mutablescope:int;id:int}andtype_expr=transient_exprandtype_desc=Tvarofstringoption|Tarrowofarg_label*type_expr*type_expr*commutable|Ttupleoftype_exprlist|TconstrofPath.t*type_exprlist*abbrev_memoref|Tobjectoftype_expr*(Path.t*type_exprlist)optionref|Tfieldofstring*field_kind*type_expr*type_expr|Tnil|Tlinkoftype_expr|Tsubstoftype_expr*type_exproption|Tvariantofrow_desc|Tunivarofstringoption|Tpolyoftype_expr*type_exprlist|TpackageofPath.t*(Longident.t*type_expr)listandrow_desc={row_fields:(label*row_field)list;row_more:type_expr;row_closed:bool;row_fixed:fixed_explanationoption;row_name:(Path.t*type_exprlist)option}andfixed_explanation=|Univaroftype_expr|Fixed_private|ReifiedofPath.t|Rigidandrow_field=[`some]row_field_genand_row_field_gen=RFpresent:type_exproption->[>`some]row_field_gen|RFeither:{no_arg:bool;arg_type:type_exprlist;matched:bool;ext:[`some|`none]row_field_genref}->[>`some]row_field_gen|RFabsent:[>`some]row_field_gen|RFnone:[>`none]row_field_genandabbrev_memo=Mnil|Mconsofprivate_flag*Path.t*type_expr*type_expr*abbrev_memo|Mlinkofabbrev_memorefandany=[`some|`none|`var]andfield_kind=[`some|`var]field_kind_genand_field_kind_gen=FKvar:{mutablefield_kind:anyfield_kind_gen}->[>`var]field_kind_gen|FKprivate:[>`none]field_kind_gen(* private method; only under FKvar *)|FKpublic:[>`some]field_kind_gen(* public method *)|FKabsent:[>`some]field_kind_gen(* hidden private method *)andcommutable=[`some|`var]commutable_genand_commutable_gen=Cok:[>`some]commutable_gen|Cunknown:[>`none]commutable_gen|Cvar:{mutablecommu:anycommutable_gen}->[>`var]commutable_genmoduleTransientTypeOps=structtypet=type_exprletcomparet1t2=t1.id-t2.idlethasht=t.idletequalt1t2=t1==t2end(* *)moduleUid=Shape.Uid(* Maps of methods and instance variables *)moduleMethSet=Misc.String.SetmoduleVarSet=Misc.String.SetmoduleMeths=Misc.String.MapmoduleVars=Misc.String.Map(* Value descriptions *)typevalue_description={val_type:type_expr;(* Type of the value *)val_kind:value_kind;val_loc:Location.t;val_attributes:Parsetree.attributes;val_uid:Uid.t;}andvalue_kind=Val_reg(* Regular value *)|Val_primofPrimitive.description(* Primitive *)|Val_ivarofmutable_flag*string(* Instance variable (mutable ?) *)|Val_selfofclass_signature*self_meths*Ident.tVars.t*string(* Self *)|Val_ancofclass_signature*Ident.tMeths.t*string(* Ancestor *)andself_meths=|Self_concreteofIdent.tMeths.t|Self_virtualofIdent.tMeths.trefandclass_signature={csig_self:type_expr;mutablecsig_self_row:type_expr;mutablecsig_vars:(mutable_flag*virtual_flag*type_expr)Vars.t;mutablecsig_meths:(method_privacy*virtual_flag*type_expr)Meths.t;}andmethod_privacy=|Mpublic|Mprivateoffield_kind(* Variance *)(* Variance forms a product lattice of the following partial orders:
0 <= may_pos <= pos
0 <= may_weak <= may_neg <= neg
0 <= inj
Additionally, the following implications are valid
pos => inj
neg => inj
Examples:
type 'a t : may_pos + may_neg + may_weak
type 'a t = 'a : pos
type 'a t = 'a -> unit : neg
type 'a t = ('a -> unit) -> unit : pos + may_weak
type 'a t = A of (('a -> unit) -> unit) : pos
type +'a p = .. : may_pos + inj
type +!'a t : may_pos + inj
type -!'a t : may_neg + inj
type 'a t = A : inj
*)moduleVariance=structtypet=inttypef=May_pos|May_neg|May_weak|Inj|Pos|Neg|Invletsingle=function|May_pos->1|May_neg->2+4|May_weak->4|Inj->8|Pos->16+8+1|Neg->32+8+4+2|Inv->63letunionv1v2=v1lorv2letinterv1v2=v1landv2letsubsetv1v2=(v1landv2=v1)leteq(v1:t)v2=(v1=v2)letsetxv=unionv(singlex)letset_ifbxv=ifbthensetxvelsevletmemx=subset(singlex)letnull=0letunknown=7letfull=singleInvletcovariant=singlePosletswapf1f2vv'=set_if(memf2v)f1(set_if(memf1v)f2v')letconjugatev=letv'=interv(union(singleInj)(singleMay_weak))inswapPosNegv(swapMay_posMay_negvv')letcomposev1v2=ifmemInvv1&&memInjv2thenfullelseletmp=memMay_posv1&&memMay_posv2||memMay_negv1&&memMay_negv2andmn=memMay_posv1&&memMay_negv2||memMay_negv1&&memMay_posv2andmw=memMay_weakv1&&v2<>null||v1<>null&&memMay_weakv2andinj=memInjv1&&memInjv2andpos=memPosv1&&memPosv2||memNegv1&&memNegv2andneg=memPosv1&&memNegv2||memNegv1&&memPosv2inList.fold_left(funv(b,f)->set_ifbfv)null[mp,May_pos;mn,May_neg;mw,May_weak;inj,Inj;pos,Pos;neg,Neg]letstrengthenv=ifmemMay_negvthenvelsevland(full-singleMay_weak)letget_upperv=(memMay_posv,memMay_negv)letget_lowerv=(memPosv,memNegv,memInjv)letunknown_signature~injective~arity=letv=ifinjectivethensetInjunknownelseunknowninMisc.replicate_listvarityendmoduleSeparability=structtypet=Ind|Sep|Deepseptypesignature=tlistleteq(m1:t)m2=(m1=m2)letrank=function|Ind->0|Sep->1|Deepsep->2letcomparem1m2=compare(rankm1)(rankm2)letmaxm1m2=ifrankm1>=rankm2thenm1elsem2letprintppf=function|Ind->Format.fprintfppf"Ind"|Sep->Format.fprintfppf"Sep"|Deepsep->Format.fprintfppf"Deepsep"letprint_signatureppfmodes=letpp_sepppf()=Format.fprintfppf",@,"inFormat.fprintfppf"@[(%a)@]"(Format.pp_print_list~pp_sepprint)modesletdefault_signature~arity=letdefault_mode=ifConfig.flat_float_arraythenDeepsepelseIndinMisc.replicate_listdefault_modearityend(* Type definitions *)typetype_declaration={type_params:type_exprlist;type_arity:int;type_kind:type_decl_kind;type_private:private_flag;type_manifest:type_exproption;type_variance:Variance.tlist;type_separability:Separability.tlist;type_is_newtype:bool;type_expansion_scope:int;type_loc:Location.t;type_attributes:Parsetree.attributes;type_immediate:Type_immediacy.t;type_unboxed_default:bool;type_uid:Uid.t;}andtype_decl_kind=(label_declaration,constructor_declaration)type_kindand('lbl,'cstr)type_kind=Type_abstract|Type_recordof'lbllist*record_representation|Type_variantof'cstrlist*variant_representation|Type_openandrecord_representation=Record_regular(* All fields are boxed / tagged *)|Record_float(* All fields are floats *)|Record_unboxedofbool(* Unboxed single-field record, inlined or not *)|Record_inlinedofint(* Inlined record *)|Record_extensionofPath.t(* Inlined record under extension *)andvariant_representation=Variant_regular(* Constant or boxed constructors *)|Variant_unboxed(* One unboxed single-field constructor *)andlabel_declaration={ld_id:Ident.t;ld_mutable:mutable_flag;ld_type:type_expr;ld_loc:Location.t;ld_attributes:Parsetree.attributes;ld_uid:Uid.t;}andconstructor_declaration={cd_id:Ident.t;cd_args:constructor_arguments;cd_res:type_exproption;cd_loc:Location.t;cd_attributes:Parsetree.attributes;cd_uid:Uid.t;}andconstructor_arguments=|Cstr_tupleoftype_exprlist|Cstr_recordoflabel_declarationlisttypeextension_constructor={ext_type_path:Path.t;ext_type_params:type_exprlist;ext_args:constructor_arguments;ext_ret_type:type_exproption;ext_private:private_flag;ext_loc:Location.t;ext_attributes:Parsetree.attributes;ext_uid:Uid.t;}andtype_transparence=Type_public(* unrestricted expansion *)|Type_new(* "new" type *)|Type_private(* private type *)(* Type expressions for the class language *)typeclass_type=Cty_constrofPath.t*type_exprlist*class_type|Cty_signatureofclass_signature|Cty_arrowofarg_label*type_expr*class_typetypeclass_declaration={cty_params:type_exprlist;mutablecty_type:class_type;cty_path:Path.t;cty_new:type_exproption;cty_variance:Variance.tlist;cty_loc:Location.t;cty_attributes:Parsetree.attributes;cty_uid:Uid.t;}typeclass_type_declaration={clty_params:type_exprlist;clty_type:class_type;clty_path:Path.t;clty_hash_type:type_declaration;clty_variance:Variance.tlist;clty_loc:Location.t;clty_attributes:Parsetree.attributes;clty_uid:Uid.t;}(* Type expressions for the module language *)typevisibility=|Exported|Hiddentypemodule_type=Mty_identofPath.t|Mty_signatureofsignature|Mty_functoroffunctor_parameter*module_type|Mty_aliasofPath.t|Mty_for_holeandfunctor_parameter=|Unit|NamedofIdent.toption*module_typeandmodule_presence=|Mp_present|Mp_absentandsignature=signature_itemlistandsignature_item=Sig_valueofIdent.t*value_description*visibility|Sig_typeofIdent.t*type_declaration*rec_status*visibility|Sig_typextofIdent.t*extension_constructor*ext_status*visibility|Sig_moduleofIdent.t*module_presence*module_declaration*rec_status*visibility|Sig_modtypeofIdent.t*modtype_declaration*visibility|Sig_classofIdent.t*class_declaration*rec_status*visibility|Sig_class_typeofIdent.t*class_type_declaration*rec_status*visibilityandmodule_declaration={md_type:module_type;md_attributes:Parsetree.attributes;md_loc:Location.t;md_uid:Uid.t;}andmodtype_declaration={mtd_type:module_typeoption;(* Note: abstract *)mtd_attributes:Parsetree.attributes;mtd_loc:Location.t;mtd_uid:Uid.t;}andrec_status=Trec_not(* first in a nonrecursive group *)|Trec_first(* first in a recursive group *)|Trec_next(* not first in a recursive/nonrecursive group *)andext_status=Text_first(* first constructor of an extension *)|Text_next(* not first constructor of an extension *)|Text_exception(* an exception *)(* Constructor and record label descriptions inserted held in typing
environments *)typeconstructor_description={cstr_name:string;(* Constructor name *)cstr_res:type_expr;(* Type of the result *)cstr_existentials:type_exprlist;(* list of existentials *)cstr_args:type_exprlist;(* Type of the arguments *)cstr_arity:int;(* Number of arguments *)cstr_tag:constructor_tag;(* Tag for heap blocks *)cstr_consts:int;(* Number of constant constructors *)cstr_nonconsts:int;(* Number of non-const constructors *)cstr_generalized:bool;(* Constrained return type? *)cstr_private:private_flag;(* Read-only constructor? *)cstr_loc:Location.t;cstr_attributes:Parsetree.attributes;cstr_inlined:type_declarationoption;cstr_uid:Uid.t;}andconstructor_tag=Cstr_constantofint(* Constant constructor (an int) *)|Cstr_blockofint(* Regular constructor (a block) *)|Cstr_unboxed(* Constructor of an unboxed type *)|Cstr_extensionofPath.t*bool(* Extension constructor
true if a constant false if a block*)letequal_tagt1t2=match(t1,t2)with|Cstr_constanti1,Cstr_constanti2->i2=i1|Cstr_blocki1,Cstr_blocki2->i2=i1|Cstr_unboxed,Cstr_unboxed->true|Cstr_extension(path1,b1),Cstr_extension(path2,b2)->Path.samepath1path2&&b1=b2|(Cstr_constant_|Cstr_block_|Cstr_unboxed|Cstr_extension_),_->falseletmay_equal_constrc1c2=c1.cstr_arity=c2.cstr_arity&&(matchc1.cstr_tag,c2.cstr_tagwith|Cstr_extension_,Cstr_extension_->(* extension constructors may be rebindings of each other *)true|tag1,tag2->equal_tagtag1tag2)letitem_visibility=function|Sig_value(_,_,vis)|Sig_type(_,_,_,vis)|Sig_typext(_,_,_,vis)|Sig_module(_,_,_,_,vis)|Sig_modtype(_,_,vis)|Sig_class(_,_,_,vis)|Sig_class_type(_,_,_,vis)->vistypelabel_description={lbl_name:string;(* Short name *)lbl_res:type_expr;(* Type of the result *)lbl_arg:type_expr;(* Type of the argument *)lbl_mut:mutable_flag;(* Is this a mutable field? *)lbl_pos:int;(* Position in block *)lbl_all:label_descriptionarray;(* All the labels in this type *)lbl_repres:record_representation;(* Representation for this record *)lbl_private:private_flag;(* Read-only field? *)lbl_loc:Location.t;lbl_attributes:Parsetree.attributes;lbl_uid:Uid.t;}letrecbound_value_identifiers=function[]->[]|Sig_value(id,{val_kind=Val_reg},_)::rem->id::bound_value_identifiersrem|Sig_typext(id,_,_,_)::rem->id::bound_value_identifiersrem|Sig_module(id,Mp_present,_,_,_)::rem->id::bound_value_identifiersrem|Sig_class(id,_,_,_)::rem->id::bound_value_identifiersrem|_::rem->bound_value_identifiersremletsignature_item_id=function|Sig_value(id,_,_)|Sig_type(id,_,_,_)|Sig_typext(id,_,_,_)|Sig_module(id,_,_,_,_)|Sig_modtype(id,_,_)|Sig_class(id,_,_,_)|Sig_class_type(id,_,_,_)->id(**** Definitions for backtracking ****)typechange=Ctypeoftype_expr*type_desc|Ccompressoftype_expr*type_desc*type_desc|Cleveloftype_expr*int|Cscopeoftype_expr*int|Cnameof(Path.t*type_exprlist)optionref*(Path.t*type_exprlist)option|Crowof[`none|`some]row_field_genref|Ckindof[`var]field_kind_gen|Ccommuof[`var]commutable_gen|Cunivoftype_exproptionref*type_exproption|Cfunof(unit->unit)typechanges=Changeofchange*changesref|Unchanged|InvalidopenLocal_storelettrail=s_tablerefUnchangedletlog_changech=letr'=refUnchangedin!trail:=Change(ch,r');trail:=r'(* constructor and accessors for [field_kind] *)typefield_kind_view=Fprivate|Fpublic|Fabsentletrecfield_kind_internal_repr:field_kind->field_kind=function|FKvar{field_kind=FKvar_|FKpublic|FKabsentasfk}->field_kind_internal_reprfk|kind->kindletfield_kind_reprfk=matchfield_kind_internal_reprfkwith|FKvar_->Fprivate|FKpublic->Fpublic|FKabsent->Fabsentletfield_public=FKpublicletfield_absent=FKabsentletfield_private()=FKvar{field_kind=FKprivate}(* Constructor and accessors for [commutable] *)letrecis_commu_ok:typea.acommutable_gen->bool=function|Cvar{commu}->is_commu_okcommu|Cunknown->false|Cok->trueletcommu_ok=Cokletcommu_var()=Cvar{commu=Cunknown}(**** Representative of a type ****)letrecrepr_link(t:type_expr)d:type_expr->type_expr=function{desc=Tlinkt'asd'}->repr_linktd't'|{desc=Tfield(_,k,_,t')asd'}whenfield_kind_internal_reprk=FKabsent->repr_linktd't'|t'->log_change(Ccompress(t,t.desc,d));t.desc<-d;t'letrepr_link1t=function{desc=Tlinkt'asd'}->repr_linktd't'|{desc=Tfield(_,k,_,t')asd'}whenfield_kind_internal_reprk=FKabsent->repr_linktd't'|t'->t'letreprt=matcht.descwithTlinkt'->repr_link1tt'|Tfield(_,k,_,t')whenfield_kind_internal_reprk=FKabsent->repr_link1tt'|_->t(* getters for type_expr *)letget_desct=(reprt).descletget_levelt=(reprt).levelletget_scopet=(reprt).scopeletget_idt=(reprt).id(* transient type_expr *)moduleTransient_expr=structletcreatedesc~level~scope~id={desc;level;scope;id}letset_desctyd=ty.desc<-dletset_stub_desctyd=assert(ty.desc=TvarNone);ty.desc<-dletset_leveltylv=ty.level<-lvletset_scopetysc=ty.scope<-scletcoercety=tyletrepr=reprlettype_exprty=tyend(* Comparison for [type_expr]; cannot be used for functors *)leteq_typet1t2=t1==t2||reprt1==reprt2letcompare_typet1t2=compare(get_idt1)(get_idt2)(* Constructor and accessors for [row_desc] *)letcreate_row~fields~more~closed~fixed~name={row_fields=fields;row_more=more;row_closed=closed;row_fixed=fixed;row_name=name}(* [row_fields] subsumes the original [row_repr] *)letrecrow_fieldsrow=matchget_descrow.row_morewith|Tvariantrow'->row.row_fields@row_fieldsrow'|_->row.row_fieldsletrecrow_repr_no_fieldsrow=matchget_descrow.row_morewith|Tvariantrow'->row_repr_no_fieldsrow'|_->rowletrow_morerow=(row_repr_no_fieldsrow).row_moreletrow_closedrow=(row_repr_no_fieldsrow).row_closedletrow_fixedrow=(row_repr_no_fieldsrow).row_fixedletrow_namerow=(row_repr_no_fieldsrow).row_nameletrecget_row_fieldtagrow=letrecfind=function|(tag',f)::fields->iftag=tag'thenfelsefindfields|[]->matchget_descrow.row_morewith|Tvariantrow'->get_row_fieldtagrow'|_->RFabsentinfindrow.row_fieldsletset_row_namerowrow_name=letrow_fields=row_fieldsrowinletrow=row_repr_no_fieldsrowin{rowwithrow_fields;row_name}typerow_desc_repr=Rowof{fields:(label*row_field)list;more:type_expr;closed:bool;fixed:fixed_explanationoption;name:(Path.t*type_exprlist)option}letrow_reprrow=letfields=row_fieldsrowinletrow=row_repr_no_fieldsrowinRow{fields;more=row.row_more;closed=row.row_closed;fixed=row.row_fixed;name=row.row_name}typerow_field_view=Rpresentoftype_exproption|Reitherofbool*type_exprlist*bool(* 1st true denotes a constant constructor *)(* 2nd true denotes a tag in a pattern matching, and
is erased later *)|Rabsentletrecrow_field_repr_auxtl:row_field->row_field=function|RFeither({ext={contents=RFnone}}asr)->RFeither{rwitharg_type=tl@r.arg_type}|RFeither{arg_type;ext={contents=RFeither_|RFpresent_|RFabsentasrf}}->row_field_repr_aux(tl@arg_type)rf|RFpresent(Some_)whentl<>[]->RFpresent(Some(List.hdtl))|RFpresent_asrf->rf|RFabsent->RFabsentletrow_field_reprfi=matchrow_field_repr_aux[]fiwith|RFeither{no_arg;arg_type;matched}->Reither(no_arg,arg_type,matched)|RFpresentt->Rpresentt|RFabsent->Rabsentletrecrow_field_ext(fi:row_field)=matchfiwith|RFeither{ext={contents=RFnone}asext}->ext|RFeither{ext={contents=RFeither_|RFpresent_|RFabsentasrf}}->row_field_extrf|_->Misc.fatal_error"Types.row_field_ext "letrf_presentoty=RFpresentotyletrf_absent=RFabsentletrf_either?use_ext_of~no_argarg_type~matched=letext=matchuse_ext_ofwithSomerf->row_field_extrf|None->refRFnoneinRFeither{no_arg;arg_type;matched;ext}letrf_either_of=function|None->RFeither{no_arg=true;arg_type=[];matched=false;ext=refRFnone}|Somety->RFeither{no_arg=false;arg_type=[ty];matched=false;ext=refRFnone}leteq_row_field_extrf1rf2=row_field_extrf1==row_field_extrf2letchanged_row_field_extslf=letexts=List.maprow_field_extlinf();List.exists(funr->!r<>RFnone)extsletmatch_row_field~present~absent~either(f:row_field)=matchfwith|RFabsent->absent()|RFpresentt->presentt|RFeither{no_arg;arg_type;matched;ext}->lete:row_fieldoption=match!extwith|RFnone->None|RFeither_|RFpresent_|RFabsentase->Someeineitherno_argarg_typematchede(**** Some type creators ****)letnew_id=Local_store.s_ref(-1)letcreate_expr=Transient_expr.createletnewty3~level~scopedesc=incrnew_id;create_exprdesc~level~scope~id:!new_idletnewty2~leveldesc=newty3~level~scope:Ident.lowest_scopedesc(**********************************)(* Utilities for backtracking *)(**********************************)letundo_change=functionCtype(ty,desc)->Transient_expr.set_desctydesc|Ccompress(ty,desc,_)->Transient_expr.set_desctydesc|Clevel(ty,level)->Transient_expr.set_leveltylevel|Cscope(ty,scope)->Transient_expr.set_scopetyscope|Cname(r,v)->r:=v|Crowr->r:=RFnone|Ckind(FKvarr)->r.field_kind<-FKprivate|Ccommu(Cvarr)->r.commu<-Cunknown|Cuniv(r,v)->r:=v|Cfunf->f()typesnapshot=changesref*intletlast_snapshot=Local_store.s_ref0letlinked_variables=s_ref0letlog_typety=ifty.id<=!last_snapshotthenlog_change(Ctype(ty,ty.desc))letlink_typetyty'=letty=reprtyinletty'=reprty'inifty==ty'then()elsebeginlog_typety;letdesc=ty.descin(matchdescwith|Tvar_->incrlinked_variables|_->());Transient_expr.set_descty(Tlinkty');(* Name is a user-supplied name for this unification variable (obtained
* through a type annotation for instance). *)matchdesc,ty'.descwithTvarname,Tvarname'->beginmatchname,name'with|Some_,None->log_typety';Transient_expr.set_descty'(Tvarname)|None,Some_->()|Some_,Some_->ifty.level<ty'.levelthen(log_typety';Transient_expr.set_descty'(Tvarname))|None,None->()end|_->()end(* ; assert (check_memorized_abbrevs ()) *)(* ; check_expans [] ty' *)(* TODO: consider eliminating set_type_desc, replacing it with link types *)letset_type_desctytd=letty=reprtyiniftd!=ty.descthenbeginlog_typety;Transient_expr.set_desctytdend(* TODO: separate set_level into two specific functions: *)(* set_lower_level and set_generic_level *)letset_leveltylevel=letty=reprtyiniflevel<>ty.levelthenbeginifty.id<=!last_snapshotthenlog_change(Clevel(ty,ty.level));Transient_expr.set_leveltylevelend(* TODO: introduce a guard and rename it to set_higher_scope? *)letset_scopetyscope=letty=reprtyinifscope<>ty.scopethenbeginifty.id<=!last_snapshotthenlog_change(Cscope(ty,ty.scope));Transient_expr.set_scopetyscopeendletset_univarrtyty=log_change(Cuniv(rty,!rty));rty:=Sometyletset_namenmv=log_change(Cname(nm,!nm));nm:=vletreclink_row_field_ext~(inside:row_field)(v:row_field)=matchinsidewith|RFeither{ext={contents=RFnone}ase}->letRFeither_|RFpresent_|RFabsentasv=vinlog_change(Crowe);e:=v|RFeither{ext={contents=RFeither_|RFpresent_|RFabsentasrf}}->link_row_field_ext~inside:rfv|_->invalid_arg"Types.link_row_field_ext"letreclink_kind~(inside:field_kind)(k:field_kind)=matchinsidewith|FKvar({field_kind=FKprivate}asrk)asinside->(* prevent a loop by normalizing k and comparing it with inside *)letFKvar_|FKpublic|FKabsentask=field_kind_internal_reprkinifk!=insidethenbeginlog_change(Ckindinside);rk.field_kind<-kend|FKvar{field_kind=FKvar_|FKpublic|FKabsentasinside}->link_kind~insidek|_->invalid_arg"Types.link_kind"letreccommu_repr:commutable->commutable=function|Cvar{commu=Cvar_|Cokascommu}->commu_reprcommu|c->cletreclink_commu~(inside:commutable)(c:commutable)=matchinsidewith|Cvar({commu=Cunknown}asrc)asinside->(* prevent a loop by normalizing c and comparing it with inside *)letCvar_|Cokasc=commu_reprcinifc!=insidethenbeginlog_change(Ccommuinside);rc.commu<-cend|Cvar{commu=Cvar_|Cokasinside}->link_commu~insidec|_->invalid_arg"Types.link_commu"letset_commu_okc=link_commu~inside:cCokletsnapshot()=letold=!last_snapshotinlast_snapshot:=!new_id;(!trail,old)letrecrev_logaccu=functionUnchanged->accu|Invalid->assertfalse|Change(ch,next)->letd=!nextinnext:=Invalid;rev_log(ch::accu)dletbacktrack~cleanup_abbrev(changes,old)=match!changeswithUnchanged->last_snapshot:=old|Invalid->failwith"Types.backtrack"|Change_aschange->cleanup_abbrev();letbacklog=rev_log[]changeinList.iterundo_changebacklog;changes:=Unchanged;last_snapshot:=old;trail:=changesletundo_first_change_after(changes,_)=match!changeswith|Change(ch,_)->undo_changech|_->()letrecrev_compress_loglogr=match!rwithUnchanged|Invalid->log|Change(Ccompress_,next)->rev_compress_log(r::log)next|Change(_,next)->rev_compress_loglognextletundo_compress(changes,_old)=match!changeswithUnchanged|Invalid->()|Change_->letlog=rev_compress_log[]changesinList.iter(funr->match!rwithChange(Ccompress(ty,desc,d),next)whenty.desc==d->Transient_expr.set_desctydesc;r:=!next|_->())log(* Merlin specific *)letlinked_variables()=!linked_variablesletis_valid(changes,_old)=match!changeswith|Invalid->false|_->trueleton_backtrackf=log_change(Cfunf)letunpack_functor=function|Mty_functor(fp,mty)->fp,mty|_->invalid_arg"Types.unpack_functor (merlin)"