this repo has no description

odoc loader: extract jkinds at Tpoly binding site only

Tvar use sites now always return Var(name, None). Jkinds are extracted
from Tunivar nodes inside the Tpoly branch, so the annotation appears
once at the universal quantifier rather than at every occurrence.

Fixes redundant ('a : value_or_null) annotations on ppx-derived types.

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

+24 -5
+24 -5
odoc/src/loader/cmi.cppo.ml
··· 611 let typ = 612 match Compat.get_desc typ with 613 #if defined OXCAML 614 - | Tvar { name; jkind } -> 615 let nm = match name with Some n -> n | None -> name_of_type typ in 616 if nm = "_" then Any 617 - else Var (nm, extract_jkind_of_tvar jkind) 618 | Tarrow((lbl, marg, mret), arg, res, _) -> 619 let arg_modes = extract_arg_modes marg in 620 let ret_modes = extract_arg_modes mret in ··· 669 | Tnil | Tfield _ -> read_object env typ None 670 | Tpoly (typ, []) -> read_type_expr env typ 671 | Tpoly (typ, tyl) -> 672 - let tyl = List.map Compat.repr tyl in 673 - let vars = List.map (fun t -> (name_of_type_repr t, None)) tyl in 674 let typ = read_type_expr env typ in 675 - remove_names tyl; 676 Poly(vars, typ) 677 #if defined OXCAML 678 | Tunivar { jkind; _ } -> Var (name_of_type typ, extract_jkind_of_tvar jkind)
··· 611 let typ = 612 match Compat.get_desc typ with 613 #if defined OXCAML 614 + | Tvar { name; _ } -> 615 + (* Tvar is a use site — don't annotate with jkind here. 616 + Jkinds are extracted at the Tunivar binding site in Tpoly, 617 + matching Printtyp's convention of stating the jkind once 618 + at the universal quantifier. *) 619 let nm = match name with Some n -> n | None -> name_of_type typ in 620 if nm = "_" then Any 621 + else Var (nm, None) 622 | Tarrow((lbl, marg, mret), arg, res, _) -> 623 let arg_modes = extract_arg_modes marg in 624 let ret_modes = extract_arg_modes mret in ··· 673 | Tnil | Tfield _ -> read_object env typ None 674 | Tpoly (typ, []) -> read_type_expr env typ 675 | Tpoly (typ, tyl) -> 676 + let reprs = List.map Compat.repr tyl in 677 + let vars = List.map2 (fun orig repr -> 678 + let name = name_of_type_repr repr in 679 + (* Extract jkind from the Tunivar binding site. 680 + This is the only place jkinds are recorded — use sites 681 + (Tvar) intentionally return None to avoid redundancy. *) 682 + let jkind = 683 + #if defined OXCAML 684 + match Compat.get_desc orig with 685 + | Tunivar { jkind; _ } -> extract_jkind_of_tvar jkind 686 + | _ -> None 687 + #else 688 + None 689 + #endif 690 + in 691 + (name, jkind)) tyl reprs 692 + in 693 let typ = read_type_expr env typ in 694 + remove_names reprs; 695 Poly(vars, typ) 696 #if defined OXCAML 697 | Tunivar { jkind; _ } -> Var (name_of_type typ, extract_jkind_of_tvar jkind)