From 2dc0473acf2bc709ba45258b8160bc416a1f95b4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 2 Jun 2026 02:17:16 +0000 Subject: [PATCH 1/2] Initial plan From 5571300f6fb68f491af3633b1e5afb9a52cb3305 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 2 Jun 2026 02:25:44 +0000 Subject: [PATCH 2/2] fix: report invalid-argument-count diagnostic at call site instead of function declaration Fixes the diagnostic target for `invalid-argument-count` errors in function calls to point at the CallExpressionNode (the call site) instead of the function declaration node. This ensures errors are shown where the function is called, not where it is defined. Co-authored-by: markcowl <1054056+markcowl@users.noreply.github.com> --- ...-function-error-location-2026-6-2-2-24-0.md | 7 +++++++ packages/compiler/src/core/checker.ts | 7 ++++--- .../compiler/test/checker/functions.test.ts | 18 ++++++++++++++++++ 3 files changed, 29 insertions(+), 3 deletions(-) create mode 100644 .chronus/changes/fix-function-error-location-2026-6-2-2-24-0.md diff --git a/.chronus/changes/fix-function-error-location-2026-6-2-2-24-0.md b/.chronus/changes/fix-function-error-location-2026-6-2-2-24-0.md new file mode 100644 index 00000000000..6556c258ccd --- /dev/null +++ b/.chronus/changes/fix-function-error-location-2026-6-2-2-24-0.md @@ -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. diff --git a/packages/compiler/src/core/checker.ts b/packages/compiler/src/core/checker.ts index 58fbf7579a4..56d42d336be 100644 --- a/packages/compiler/src/core/checker.ts +++ b/packages/compiler/src/core/checker.ts @@ -5812,7 +5812,7 @@ export function createChecker(program: Program, resolver: NameResolver): Checker node: CallExpressionNode, target: FunctionValue, ): Type | Value | null { - const [satisfied, resolvedArgs] = checkFunctionCallArguments(ctx, node.arguments, target); + const [satisfied, resolvedArgs] = checkFunctionCallArguments(ctx, node.arguments, target, node); const canCall = satisfied && @@ -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; @@ -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, []]; @@ -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. diff --git a/packages/compiler/test/checker/functions.test.ts b/packages/compiler/test/checker/functions.test.ts index fee33f9343b..f9daf27db61 100644 --- a/packages/compiler/test/checker/functions.test.ts +++ b/packages/compiler/test/checker/functions.test.ts @@ -6,6 +6,7 @@ import { IndeterminateEntity, Model, Namespace, + SyntaxKind, Type, Value, } from "../../src/core/types.js"; @@ -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[])",