this repo has no description
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat(odoc): capture mode/jkind info from OxCaml compiler in loader

- cmi.ml: Extract argument modes from Tarrow via Mode.Alloc.zap_to_legacy
and diff against legacy defaults (replicating Printtyp.tree_of_modes logic)
- cmi.ml: Extract jkind/layout from Tvar/Tunivar via Jkind.get descriptor
- cmti.ml: Extract jkind annotation from Ttyp_var's Parsetree annotation
- All extraction is cppo-guarded with OXCAML; standard OCaml passes []/None

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

+78 -8
+69 -4
src/loader/cmi.ml
··· 492 492 List.iter mark_type_parameter cld.cty_params; 493 493 mark_class_type cld.cty_params cld.cty_type 494 494 495 + #if defined OXCAML 496 + (** Extract non-default mode strings from an OxCaml argument mode. 497 + Replicates the logic from [Printtyp.tree_of_modes]. *) 498 + let extract_arg_modes marg = 499 + let modes = Mode.Alloc.zap_to_legacy marg in 500 + let diff = Mode.Alloc.Const.diff modes Mode.Alloc.Const.legacy in 501 + (* Apply implied-default elision rules from Printtyp *) 502 + let forkable = 503 + match modes.areality, modes.forkable with 504 + | Local, Unforkable | Global, Forkable -> None 505 + | _, _ -> diff.forkable 506 + in 507 + let yielding = 508 + match modes.areality, modes.yielding with 509 + | Local, Yielding | Global, Unyielding -> None 510 + | _, _ -> diff.yielding 511 + in 512 + let contention = 513 + match modes.visibility, modes.contention with 514 + | Immutable, Contended | Read, Shared | Read_write, Uncontended -> None 515 + | _, _ -> diff.contention 516 + in 517 + let portability = 518 + match modes.statefulness, modes.portability with 519 + | Stateless, Portable | Observing, Shareable | Stateful, Nonportable -> None 520 + | _, _ -> diff.portability 521 + in 522 + let print_opt print a = 523 + Option.map (fun v -> Format.asprintf "%a" print v) a 524 + in 525 + List.filter_map Fun.id 526 + [ print_opt Mode.Locality.Const.print diff.areality 527 + ; print_opt Mode.Uniqueness.Const.print diff.uniqueness 528 + ; print_opt Mode.Linearity.Const.print diff.linearity 529 + ; print_opt Mode.Portability.Const.print portability 530 + ; print_opt Mode.Contention.Const.print contention 531 + ; print_opt Mode.Forkable.Const.print forkable 532 + ; print_opt Mode.Yielding.Const.print yielding 533 + ; print_opt Mode.Statefulness.Const.print diff.statefulness 534 + ; print_opt Mode.Visibility.Const.print diff.visibility ] 535 + 536 + (** Extract jkind/layout string from an OxCaml type variable's jkind. 537 + Returns [None] for the default [value] layout or unknown layouts. *) 538 + let extract_jkind_of_tvar jkind = 539 + let desc = Jkind.get jkind in 540 + match desc.base with 541 + | Layout (Sort (Base Value)) -> None (* default — don't annotate *) 542 + | Layout (Sort (Base b)) -> Some (Jkind_types.Sort.to_string_base b) 543 + | Layout (Sort (Var _)) -> None (* sort variable — not determined *) 544 + | Layout (Sort (Univar _)) -> None (* universally quantified sort *) 545 + | Layout (Product _) -> None (* product layout — complex, skip for now *) 546 + | Layout Any -> None 547 + | Kconstr _ -> None (* abstract kind — skip *) 548 + #endif 549 + 495 550 let rec read_type_expr env typ = 496 551 let open TypeExpr in 497 552 let px = proxy typ in ··· 506 561 in 507 562 let typ = 508 563 match Compat.get_desc typ with 564 + #if defined OXCAML 565 + | Tvar { name; jkind } -> 566 + let nm = match name with Some n -> n | None -> name_of_type typ in 567 + if nm = "_" then Any 568 + else Var (nm, extract_jkind_of_tvar jkind) 569 + | Tarrow((lbl, marg, _mret), arg, res, _) -> 570 + let arg_modes = extract_arg_modes marg in 571 + #else 509 572 | Tvar _ -> 510 573 let name = name_of_type typ in 511 574 if name = "_" then Any 512 575 else Var (name, None) 513 - #if defined OXCAML 514 - | Tarrow((lbl,_,_), arg, res, _) -> 515 - #else 516 576 | Tarrow(lbl, arg, res, _) -> 577 + let arg_modes = [] in 517 578 #endif 518 579 let lbl = read_label lbl in 519 580 let lbl,arg = ··· 535 596 lbl, read_type_expr env arg 536 597 in 537 598 let res = read_type_expr env res in 538 - Arrow(lbl, arg, res, []) 599 + Arrow(lbl, arg, res, arg_modes) 539 600 | Ttuple typs -> 540 601 #if OCAML_VERSION >= (5,4,0) || defined OXCAML 541 602 let typs = List.map (fun (lbl,x) -> lbl, read_type_expr env x) typs in ··· 562 623 let typ = read_type_expr env typ in 563 624 remove_names tyl; 564 625 Poly(vars, typ) 626 + #if defined OXCAML 627 + | Tunivar { jkind; _ } -> Var (name_of_type typ, extract_jkind_of_tvar jkind) 628 + #else 565 629 | Tunivar _ -> Var (name_of_type typ, None) 630 + #endif 566 631 #if OCAML_VERSION>=(5,4,0) 567 632 | Tpackage {pack_path=p; pack_cstrs } -> 568 633 let eqs = List.filter_map (fun (l,ty) -> Option.map (fun x -> x, ty) (Longident.unflatten l)) pack_cstrs in
+9 -4
src/loader/cmti.ml
··· 44 44 let open TypeExpr in 45 45 match ctyp.ctyp_desc with 46 46 #if defined OXCAML 47 - (* TODO: presumably we want the layout in these first two cases, 48 - eventually *) 49 - | Ttyp_var (None, _layout) -> Any 50 - | Ttyp_var (Some s, _layout) -> Var (s, None) 47 + | Ttyp_var (None, _jkind_annot) -> Any 48 + | Ttyp_var (Some s, jkind_annot) -> 49 + let jkind = match jkind_annot with 50 + | Some { Parsetree.pjka_desc = Pjk_abbreviation lid; _ } -> 51 + let name = Longident.last lid.txt in 52 + if name = "value" then None else Some name 53 + | _ -> None 54 + in 55 + Var (s, jkind) 51 56 #else 52 57 | Ttyp_any -> Any 53 58 | Ttyp_var s -> Var (s, None)