Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
changeKind: fix
packages:
- "@typespec/compiler"
---

Fixed `invalid-argument-count` diagnostic for function calls to report on the call expression instead of the function declaration.
7 changes: 4 additions & 3 deletions packages/compiler/src/core/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5812,7 +5812,7 @@ export function createChecker(program: Program, resolver: NameResolver): Checker
node: CallExpressionNode,
target: FunctionValue<unknown[]>,
): Type | Value | null {
const [satisfied, resolvedArgs] = checkFunctionCallArguments(ctx, node.arguments, target);
const [satisfied, resolvedArgs] = checkFunctionCallArguments(ctx, node.arguments, target, node);

const canCall =
satisfied &&
Expand Down Expand Up @@ -5914,6 +5914,7 @@ export function createChecker(program: Program, resolver: NameResolver): Checker
ctx: CheckContext,
args: Expression[],
target: FunctionValue,
callNode: CallExpressionNode,
): [boolean, any[]] {
let satisfied = true;
const minArgs = target.parameters.filter((p) => !p.optional && !p.rest).length;
Expand All @@ -5927,7 +5928,7 @@ export function createChecker(program: Program, resolver: NameResolver): Checker
code: "invalid-argument-count",
messageId: "atLeast",
format: { actual: args.length.toString(), expected: minArgs.toString() },
target: target.node!,
target: callNode,
}),
);
return [false, []];
Expand All @@ -5936,7 +5937,7 @@ export function createChecker(program: Program, resolver: NameResolver): Checker
createDiagnostic({
code: "invalid-argument-count",
format: { actual: args.length.toString(), expected: maxArgs.toString() },
target: target.node!,
target: callNode,
}),
);
// This error doesn't actually prevent us from checking the arguments and evaluating the function.
Expand Down
18 changes: 18 additions & 0 deletions packages/compiler/test/checker/functions.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
IndeterminateEntity,
Model,
Namespace,
SyntaxKind,
Type,
Value,
} from "../../src/core/types.js";
Expand Down Expand Up @@ -365,6 +366,23 @@ describe("usage", () => {
strictEqual(v.value, "one");
});

it("reports invalid-argument-count error at call site, not function declaration", async () => {
const fnTester = createTesterForFn("testFn", testFnImpl);
const [, diagnostics] = await fnTester.compileAndDiagnose(`
extern fn testFn(a: valueof string): valueof string;
const X = testFn("one", "two");
`);

const argCountDiag = diagnostics.find((d) => d.code === "invalid-argument-count");
ok(argCountDiag, "Expected invalid-argument-count diagnostic");
ok(argCountDiag.target !== undefined, "Expected diagnostic to have a target");
strictEqual(
(argCountDiag.target as any).kind,
SyntaxKind.CallExpression,
"Diagnostic should target the call expression, not the function declaration",
);
});

it("errors if too few with rest", async () => {
const t = await expectFunctionTypeUsage(
"extern fn testFn(a: string, ...rest: string[])",
Expand Down
Loading