You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Represent optional parameters with defaults structurally instead of by name sniffing
The desugaring of an optional parameter with a default (~x=3) binds the
option-carrying parameter to a synthetic *opt_<label>* variable, and that
fact was recovered downstream by pattern-matching on the variable name in
four places across three compiler layers: typecore's is_fake_let (matching
the pre-n-ary name "*opt*" exactly, so it had silently rotted into dead
code), matching's *sth* let-elimination peephole, lam_convert's
rename_optional_parameters (which also had to re-recognize the whole
compiled body shape to rename the parameter to xOpt for JS output), and
gentype's *opt prefix check.
Represent the fact structurally instead:
- Typedtree.function_param gains an fp_has_default field.
- type_function replaces the carrier ident right after typing: fp_param
becomes a fresh ident named <label>Opt, substituted at the carrier's
only two occurrences (the parameter pattern's binder and the synthetic
match's scrutinee), both nodes the desugaring itself generated. The
unspellable name still exists during typing, where names must be
impossible to capture or shadow, but dies before the typedtree leaves
the function. The Lambda IR is born with the final parameter name and
no residual binding.
- lam_convert's rename_optional_parameters and is_opt_param_name are
deleted; the Lfunction case is a plain conversion.
- matching's *sth* peephole is generalized to eliminate any alias binding
of the form let v = arg in v, with no name test.
- gentype uses fp_has_default instead of sniffing the ident name.
- is_fake_let now keys on the #optional_arg_default attribute the
desugaring plants, restoring its intended behavior: an unused defaulted
parameter warns as an unused parameter (27), not an unused let (26).
- The write-only #default attribute is removed, along with its dead
parsetree consumer.
Visible improvements: parameter names in emitted JS now consistently
derive from the label, including cases the old shape-match silently
missed and leaked mangled names for (mario_game.mjs's make$2 had
$staropt_id$star as a parameter; it is now idOpt).
Signed-Off-By: Cristiano Calcagno <ccrisccris@gmail.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PCtQiaDijUqA2fujQXvKUw
0 commit comments