123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208(**************************************************************************)(* *)(* OCaml *)(* *)(* Florian Angeletti, projet Cambium, Inria Paris *)(* Antal Spector-Zabusky, Jane Street, New York *)(* *)(* Copyright 2018 Institut National de Recherche en Informatique et *)(* en Automatique. *)(* Copyright 2021 Jane Street Group LLC *)(* *)(* 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. *)(* *)(**************************************************************************)openTypesopenFormattypeposition=First|Secondletswap_position=function|First->Second|Second->Firstletprint_posppf=function|First->fprintfppf"first"|Second->fprintfppf"second"typeexpanded_type={ty:type_expr;expanded:type_expr}lettrivial_expansionty={ty;expanded=ty}type'adiff={got:'a;expected:'a}letmap_difffr=(* ordering is often meaningful when dealing with type_expr *)letgot=fr.gotinletexpected=fr.expectedin{got;expected}letswap_diffx={got=x.expected;expected=x.got}type'aescape_kind=|ConstructorofPath.t|Univoftype_expr(* The type_expr argument of [Univ] is always a [Tunivar _],
we keep a [type_expr] to track renaming in {!Printtyp} *)|Self|Module_typeofPath.t|Equationof'a|Constrainttype'aescape={kind:'aescape_kind;context:type_exproption}letmap_escapefesc={escwithkind=matchesc.kindwith|Equationeq->Equation(feq)|(Constructor_|Univ_|Self|Module_type_|Constraint)asc->c}letexplaintracef=letrecexplain=function|[]->None|[h]->f~prev:Noneh|h::(prev::_asrem)->matchf~prev:(Someprev)hwith|Some_asm->m|None->explainreminexplain(List.revtrace)(* Type indices *)typeunification=privateUnificationtypecomparison=privateComparisontypefixed_row_case=|Cannot_be_closed|Cannot_add_tagsofstringlisttype'varietyvariant=(* Common *)|Incompatible_types_for:string->_variant|No_tags:position*(Asttypes.label*row_field)list->_variant(* Unification *)|No_intersection:unificationvariant|Fixed_row:position*fixed_row_case*fixed_explanation->unificationvariant(* Equality & Moregen *)|Presence_not_guaranteed_for:position*string->comparisonvariant|Openness:position(* Always [Second] for Moregen *)->comparisonvarianttype'varietyobj=(* Common *)|Missing_field:position*string->_obj|Abstract_row:position->_obj(* Unification *)|Self_cannot_be_closed:unificationobjtype('a,'variety)elt=(* Common *)|Diff:'adiff->('a,_)elt|Variant:'varietyvariant->('a,'variety)elt|Obj:'varietyobj->('a,'variety)elt|Escape:'aescape->('a,_)elt|Incompatible_fields:{name:string;diff:type_exprdiff}->('a,_)elt(* Could move [Incompatible_fields] into [obj] *)(* Unification & Moregen; included in Equality for simplicity *)|Rec_occur:type_expr*type_expr->('a,_)elttype('a,'variety)t=('a,'variety)eltlisttype'varietytrace=(type_expr,'variety)ttype'varietyerror=(expanded_type,'variety)tletmap_descf{ty;expanded}=letty=ftyinletexpanded=fexpandedin{ty;expanded}letmap_elt(typevariety)f:('a,variety)elt->('b,variety)elt=function|Diffx->Diff(map_difffx)|Escape{kind=Equationx;context}->Escape{kind=Equation(fx);context}|Escape{kind=(Univ_|Self|Constructor_|Module_type_|Constraint);_}|Variant_|Obj_|Incompatible_fields_|Rec_occur(_,_)asx->xletmapft=List.map(map_eltf)tletmap_typesf=map(map_descf)letincompatible_fields~name~got~expected=Incompatible_fields{name;diff={got;expected}}letswap_elt(typevariety):('a,variety)elt->('a,variety)elt=function|Diffx->Diff(swap_diffx)|Incompatible_fields{name;diff}->Incompatible_fields{name;diff=swap_diffdiff}|Obj(Missing_field(pos,s))->Obj(Missing_field(swap_positionpos,s))|Obj(Abstract_rowpos)->Obj(Abstract_row(swap_positionpos))|Variant(Fixed_row(pos,k,f))->Variant(Fixed_row(swap_positionpos,k,f))|Variant(No_tags(pos,f))->Variant(No_tags(swap_positionpos,f))|x->xletswap_tracee=List.mapswap_eltetypeunification_error={trace:unificationerror}[@@unboxed]typeequality_error={trace:comparisonerror;subst:(type_expr*type_expr)list}typemoregen_error={trace:comparisonerror}[@@unboxed]letunification_error~trace:unification_error=assert(trace<>[]);{trace}letequality_error~trace~subst:equality_error=assert(trace<>[]);{trace;subst}letmoregen_error~trace:moregen_error=assert(trace<>[]);{trace}typecomparison_error=|Equality_errorofequality_error|Moregen_errorofmoregen_errorletswap_unification_error({trace}:unification_error)=({trace=swap_tracetrace}:unification_error)moduleSubtype=structtype'aelt=|Diffof'adifftype'at='aeltlisttypetrace=type_exprttypeerror_trace=expanded_typettypeunification_error_trace=unificationerror(** To avoid shadowing *)typenonrecerror={trace:error_trace;unification_trace:unificationerror}leterror~trace~unification_trace=assert(trace<>[]);{trace;unification_trace}letmap_eltf=function|Diffx->Diff(map_difffx)letmapft=List.map(map_eltf)tletmap_descf{ty;expanded}=letty=ftyinletexpanded=fexpandedin{ty;expanded}letmap_typesf=map(map_descf)end