SMTH3(5) -- one argument to a function that needs at least an input and a
delay time -- compiles, produces no diagnostic, and simulates.
Repro (simlin simulate):
<aux name="s3"><eqn>SMTH3(5)</eqn></aux>
Output: delay_time = 1 (the stdlib model's own default), initial_value =
NaN, s3 = 5 for every step. No error, no warning.
Cause: builtins_visitor::expand_module_function
(src/simlin-engine/src/builtins_visitor.rs:1015) checks arity only for project
macros:
if descriptor.is_macro && args.len() != descriptor.parameter_ports.len() {
ModuleFunctionDescriptor::is_macro is documented as the leniency switch:
stdlib functions "permit fewer arguments than ports (trailing ports are
optional)" (src/simlin-engine/src/module_functions.rs:51). That is true of the
TRAILING port only -- SMTH1/SMTH3/DELAY1/DELAY3/TREND may leave
initial_value unwired, and NPV may leave initial_value/factor unwired --
but the leniency is written as "no check at all", so a call with zero or one
argument passes too. Expr1::from's BuiltinSig arity check never sees these
calls: a stdlib module function is not a BuiltinSig.
Fix shape: give the descriptor a required-port count beside
parameter_ports (for stdlib, the ports that are not optional: 2 for the
smth*/delay*/trend family, 2 for npv; for a macro, all of them), and
reject args.len() < required with BadBuiltinArgs over the call span, keeping
the existing exact-arity rule for macros. Test rows should be derived from
module_functions::stdlib_args' match arms, so a stdlib function added later
cannot silently skip the check.
Pre-existing; found while reviewing the compiler-unification Phase 5b commit
(engine: diagnostics keep their message from parse to collection), which
touched the neighbouring arity message but not this gate.
SMTH3(5)-- one argument to a function that needs at least an input and adelay time -- compiles, produces no diagnostic, and simulates.
Repro (
simlin simulate):Output:
delay_time= 1 (the stdlib model's own default),initial_value=NaN,
s3= 5 for every step. No error, no warning.Cause:
builtins_visitor::expand_module_function(
src/simlin-engine/src/builtins_visitor.rs:1015) checks arity only for projectmacros:
ModuleFunctionDescriptor::is_macrois documented as the leniency switch:stdlib functions "permit fewer arguments than ports (trailing ports are
optional)" (
src/simlin-engine/src/module_functions.rs:51). That is true of theTRAILING port only --
SMTH1/SMTH3/DELAY1/DELAY3/TRENDmay leaveinitial_valueunwired, andNPVmay leaveinitial_value/factorunwired --but the leniency is written as "no check at all", so a call with zero or one
argument passes too.
Expr1::from'sBuiltinSigarity check never sees thesecalls: a stdlib module function is not a
BuiltinSig.Fix shape: give the descriptor a required-port count beside
parameter_ports(for stdlib, the ports that are not optional: 2 for thesmth*/delay*/trendfamily, 2 fornpv; for a macro, all of them), andreject
args.len() < requiredwithBadBuiltinArgsover the call span, keepingthe existing exact-arity rule for macros. Test rows should be derived from
module_functions::stdlib_args' match arms, so a stdlib function added latercannot silently skip the check.
Pre-existing; found while reviewing the compiler-unification Phase 5b commit
(
engine: diagnostics keep their message from parse to collection), whichtouched the neighbouring arity message but not this gate.