Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file ppx_deriving_eq.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216openPpxlibopenAsttypesopenParsetreeopenAst_helperopenPpx_deriving.Ast_convenienceletderiver="eq"letraise_errorf=Ppx_deriving.raise_errorfletct_attr_nobuiltin=Attribute.declare_flag"deriving.eq.nobuiltin"Attribute.Context.core_typeletct_attr_equal=Attribute.declare"deriving.eq.equal"Attribute.Context.core_typeAst_pattern.(single_expr_payload__)(fune->e)letargnkind=Printf.sprintf(matchkindwith`lhs->"lhs%d"|`rhs->"rhs%d")letarglkind=Printf.sprintf(matchkindwith`lhs->"lhs%s"|`rhs->"rhs%s")letpattnsidetyps=List.mapi(funi_->pvar(argnsidei))typsletpattlsidelabels=List.map(fun{pld_name={txt=n}}->n,pvar(arglsiden))labelsletpconstrrecnamefields=pconstrname[precord~closed:Closedfields]letcore_type_of_decltype_decl=letloc=!Ast_helper.default_locinlettyp=Ppx_deriving.core_type_of_type_decltype_declinPpx_deriving.poly_arrow_of_type_decl(funvar->[%type:[%tvar]->[%tvar]->Ppx_deriving_runtime.bool])type_decl[%type:[%ttyp]->[%ttyp]->Ppx_deriving_runtime.bool]letsig_of_typetype_decl=[Sig.value(Val.mk(mknoloc(Ppx_deriving.mangle_type_decl(`Prefix"equal")type_decl))(core_type_of_decltype_decl))]letrecexprnquotertyps=typs|>List.mapi(funityp->app(expr_of_typquotertyp)[evar(argn`lhsi);evar(argn`rhsi)])andexprlquotertyps=typs|>List.map(fun({pld_name={txt=n};pld_loc;_}aspld)->with_default_locpld_loc@@fun()->app(expr_of_label_declquoterpld)[evar(argl`lhsn);evar(argl`rhsn)])andexpr_of_label_declquoter{pld_type;pld_attributes}=letattrs=pld_type.ptyp_attributes@pld_attributesinexpr_of_typquoter{pld_typewithptyp_attributes=attrs}andexpr_of_typquotertyp=letloc=!Ast_helper.default_locinlettyp=Ppx_deriving.remove_pervasives~derivertypinletexpr_of_typ=expr_of_typquoterinmatchAttribute.getct_attr_equaltypwith|Somefn->Ppx_deriving.quote~quoterfn|None->matchtypwith|[%type:_]->[%exprfun__->true]|{ptyp_desc=Ptyp_constr_}->letbuiltin=not(Attribute.has_flagct_attr_nobuiltintyp)inbeginmatchbuiltin,typwith|true,[%type:unit]->[%exprfun(_:unit)(_:unit)->true]|true,([%type:int]|[%type:int32]|[%type:Int32.t]|[%type:int64]|[%type:Int64.t]|[%type:nativeint]|[%type:Nativeint.t]|[%type:float]|[%type:bool]|[%type:char]|[%type:string]|[%type:bytes])->[%expr(fun(a:[%ttyp])b->a=b)]|true,[%type:[%t?typ]ref]->[%exprfunab->[%eexpr_of_typtyp]!a!b]|true,[%type:[%t?typ]list]->[%exprletrecloopxy=matchx,ywith|[],[]->true|a::x,b::y->[%eexpr_of_typtyp]ab&&loopxy|_->falsein(funxy->loopxy)]|true,[%type:[%t?typ]array]->[%exprfunxy->letrecloopi=i=Array.lengthx||([%eexpr_of_typtyp]x.(i)y.(i)&&loop(i+1))inArray.lengthx=Array.lengthy&&loop0]|true,[%type:[%t?typ]option]->[%exprfunxy->matchx,ywith|None,None->true|Somea,Someb->[%eexpr_of_typtyp]ab|_->false]|true,([%type:([%t?ok_t],[%t?err_t])result]|[%type:([%t?ok_t],[%t?err_t])Result.result])->[%exprfunxy->matchx,ywith|Oka,Okb->[%eexpr_of_typok_t]ab|Errora,Errorb->[%eexpr_of_typerr_t]ab|_->false]|true,([%type:[%t?typ]lazy_t]|[%type:[%t?typ]Lazy.t])->[%exprfun(lazyx)(lazyy)->[%eexpr_of_typtyp]xy]|_,{ptyp_desc=Ptyp_constr({txt=lid},args)}->letequal_fn=Exp.ident(mknoloc(Ppx_deriving.mangle_lid(`Prefix"equal")lid))inapp(Ppx_deriving.quote~quoterequal_fn)(List.mapexpr_of_typargs)|_->assertfalseend|{ptyp_desc=Ptyp_tupletyps}->[%exprfun[%pptuple(pattn`lhstyps)][%pptuple(pattn`rhstyps)]->[%eexprnquotertyps|>Ppx_deriving.(fold_exprs(binop_reduce[%expr(&&)]))]]|{ptyp_desc=Ptyp_variant(fields,_,_);ptyp_loc}->letcases=(fields|>List.map(funfield->letpdupf=ptuple[f"lhs";f"rhs"]inletvariantlabelpopt=Pat.variantlabel.txtpoptinmatchfield.prf_descwith|Rtag(label,true(*empty*),[])->Exp.case(pdup(fun_->variantlabelNone))[%exprtrue]|Rtag(label,false,[typ])->Exp.case(pdup(funvar->variantlabel(Some(pvarvar))))(app(expr_of_typtyp)[evar"lhs";evar"rhs"])|Rinherit({ptyp_desc=Ptyp_constr(tname,_)}astyp)->Exp.case(pdup(funvar->Pat.alias(Pat.type_tname)(mknolocvar)))(app(expr_of_typtyp)[evar"lhs";evar"rhs"])|_->raise_errorf~loc:ptyp_loc"%s cannot be derived for %s"deriver(Ppx_deriving.string_of_core_typetyp)))@[Exp.case(pvar"_")[%exprfalse]]in[%exprfunlhsrhs->[%eExp.match_[%exprlhs,rhs]cases]]|{ptyp_desc=Ptyp_varname}->evar("poly_"^name)|{ptyp_desc=Ptyp_alias(typ,_)}->expr_of_typtyp|{ptyp_loc}->raise_errorf~loc:ptyp_loc"%s cannot be derived for %s"deriver(Ppx_deriving.string_of_core_typetyp)letstr_of_type({ptype_loc=loc}astype_decl)=letquoter=Ppx_deriving.create_quoter()inletcomparator=matchtype_decl.ptype_kind,type_decl.ptype_manifestwith|Ptype_abstract,Somemanifest->expr_of_typquotermanifest|Ptype_variantconstrs,_->letcases=(constrs|>List.map(fun{pcd_name={txt=name};pcd_args;pcd_loc}->with_default_locpcd_loc@@fun()->matchpcd_argswith|Pcstr_tuple(typs)->exprnquotertyps|>Ppx_deriving.(fold_exprs~unit:[%exprtrue](binop_reduce[%expr(&&)]))|>Exp.case(ptuple[pconstrname(pattn`lhstyps);pconstrname(pattn`rhstyps)])|Pcstr_record(labels)->exprlquoterlabels|>Ppx_deriving.(fold_exprs~unit:[%exprtrue](binop_reduce[%expr(&&)]))|>Exp.case(ptuple[pconstrrecname(pattl`lhslabels);pconstrrecname(pattl`rhslabels)])))@[Exp.case(pvar"_")[%exprfalse]]in[%exprfunlhsrhs->[%eExp.match_[%exprlhs,rhs]cases]]|Ptype_recordlabels,_->letexprs=labels|>List.map(fun({pld_loc;pld_name={txt=name};_}aspld)->with_default_locpld_loc@@fun()->(* combine attributes of type and label *)letfieldobj=Exp.fieldobj(mknoloc(Lidentname))inapp(expr_of_label_declquoterpld)[field(evar"lhs");field(evar"rhs")])in[%exprfunlhsrhs->[%eexprs|>Ppx_deriving.(fold_exprs(binop_reduce[%expr(&&)]))]]|Ptype_abstract,None->raise_errorf~loc"%s cannot be derived for fully abstract types"deriver|Ptype_open,_->raise_errorf~loc"%s cannot be derived for open types"deriverinletpolymorphize=Ppx_deriving.poly_fun_of_type_decltype_declinleteta_expandexpr=(* Ensure expr is statically constructive by eta-expanding non-funs.
See https://github.com/ocaml-ppx/ppx_deriving/pull/252. *)matchexprwith|{pexp_desc=Pexp_fun_;_}->expr|_->[%exprfunx->[%eexpr]x]inletout_type=Ppx_deriving.strong_type_of_type@@core_type_of_decltype_declinleteq_var=pvar(Ppx_deriving.mangle_type_decl(`Prefix"equal")type_decl)in[Vb.mk~attrs:[Ppx_deriving.attr_warning[%expr"-39"]](Pat.constraint_eq_varout_type)(Ppx_deriving.sanitize~quoter(eta_expand(polymorphizecomparator)))]letimpl_generator=Deriving.Generator.V2.make_noarg(fun~ctxt:_(_,type_decls)->[Str.valueRecursive(List.concat(List.mapstr_of_typetype_decls))])letintf_generator=Deriving.Generator.V2.make_noarg(fun~ctxt:_(_,type_decls)->List.concat(List.mapsig_of_typetype_decls))letderiving:Deriving.t=Deriving.addderiver~str_type_decl:impl_generator~sig_type_decl:intf_generator(* custom extension such that "derive"-prefixed also works *)letderive_extension=Extension.V3.declare"derive.eq"Extension.Context.expressionAst_pattern.(ptyp__)(fun~ctxt:_->Ppx_deriving.with_quoterexpr_of_typ)letderive_transformation=Driver.register_transformationderiver~rules:[Context_free.Rule.extensionderive_extension]