Keep @tag and runtime annotations when printing a type declaration
Why
The printer of type declarations kept only @immediate and @unboxed. @tag, @notUndefined, @instanceOf and @typeOf were dropped, so a signature mismatch about them printed two declarations that looked the same, hover hid them, and createInterface wrote an interface for an applied functor that does not match its implementation (#9134).
modifiedDiagnostic @tag mismatch
// Foo.res@tag("type")type t = | @as("a") A | B// Foo.resi@tag("kind")type t = | @as("a") A | B
diagnostic
modifiedDiagnostic @notUndefined functor parameter
module Make = ( X: { @notUndefined type t },) => { type u = X.t}module Applied = Make({ type t = option<int>})
diagnostic
modifiedFormat createInterface for an applied functor
module Tagged = (X: Type) => { @tag("kind") type wrapped = Value({value: X.t}) | Empty({reason: string})}module IntTagged = Tagged({ type t = int})
rescript
modifiedRepresentation printed declaration annotations, Printtyp.tree_of_type_decl
representation
Review
- Why read the attributes rather than the declaration's runtime shape? The shape of an abbreviation can come from the type it abbreviates; the printed declaration should show what it states itself, as the source does.
- Can printing raise for a malformed annotation? No. The annotations are parsed by the functions that typing uses, which raise on malformed payloads; those were reported when the declaration was typed, and the printer then leaves the annotation out.