installparams normalizes a decl's `T...` param lhs to []T in place (cstage instead sets the resolved tp->type and never mutates AST), so typeeqast compared a decl-synthesized fn type's []i64 against a fn TYPE expr's surface i64 and confidently rejected `let f: fn(args: i64...) void = sum;` — cstage accepts and runs. The normalization wrapper now carries an op marker and typeeqast peels exactly it, so both sides compare at the declared element type without admitting genuinely different element depths. Fixture fnptrlet_variadic; corpus pin 1486/2972.
22 lines
643 B
Plaintext
22 lines
643 B
Plaintext
//ww:run-exit 42
|
|
package main;
|
|
|
|
// A variadic fn assigned to a fn-typed let and called through it. The
|
|
// wwstage over-rejected the let ("not assignable"): installparams
|
|
// normalizes the DECL's `T...` param lhs to []T in place, while the
|
|
// let's fn TYPE expr stays surface, so typeeqast compared []i64 vs
|
|
// i64. cstage compares resolved types with type_slice on both sides
|
|
// (check.c:908-917) and accepts.
|
|
|
|
fn tally(args: i64...) i64 = {
|
|
let s: i64 = 0i64;
|
|
let i: i32 = 0;
|
|
for (i < args.len) { s += args[i]; i += 1; };
|
|
return s;
|
|
};
|
|
|
|
fn main() i32 = {
|
|
let f: fn(args: i64...) i64 = tally;
|
|
return (f(1i64, 2i64, 3i64) * 7i64): i32;
|
|
};
|