diff --git a/.chronus/changes/fix-crash-spread-versioning-2024-6-23-14-37-28.md b/.chronus/changes/fix-crash-spread-versioning-2024-6-23-14-37-28.md new file mode 100644 index 0000000000..662d0e47f5 --- /dev/null +++ b/.chronus/changes/fix-crash-spread-versioning-2024-6-23-14-37-28.md @@ -0,0 +1,7 @@ +--- +changeKind: fix +packages: + - "@typespec/versioning" +--- + +Fixes issue where spreading a versioned model as a parameter to an incompatible versioned operation would cause the compiler to crash. \ No newline at end of file diff --git a/packages/versioning/src/validate.ts b/packages/versioning/src/validate.ts index 57e1ca178a..ac7ac09613 100644 --- a/packages/versioning/src/validate.ts +++ b/packages/versioning/src/validate.ts @@ -104,6 +104,11 @@ export function $onValidate(program: Program) { validateTargetVersionCompatible(program, op.interface, op, { isTargetADependent: true }); } validateReference(program, op, op.returnType); + + // Check that any spread/is/aliased models are valid for this operation + for (const sourceModel of op.parameters.sourceModels) { + validateReference(program, op, sourceModel.model); + } }, interface: (iface) => { for (const source of iface.sourceInterfaces) { diff --git a/packages/versioning/test/incompatible-versioning.test.ts b/packages/versioning/test/incompatible-versioning.test.ts index 6495d6b86c..c681ca9eb3 100644 --- a/packages/versioning/test/incompatible-versioning.test.ts +++ b/packages/versioning/test/incompatible-versioning.test.ts @@ -131,6 +131,24 @@ describe("versioning: validate incompatible references", () => { ); }); + it("emit diagnostic when versioned op has a newer versioned spread parameter", async () => { + const diagnostics = await runner.diagnose(` + @added(Versions.v2) + model MyOptions { + prop: string; + } + + @added(Versions.v1) + op foo(...MyOptions,): void; + `); + + expectDiagnostics(diagnostics, { + code: "@typespec/versioning/incompatible-versioned-reference", + message: + "'TestService.foo' was added in version 'v1' but referencing type 'TestService.MyOptions' added in version 'v2'.", + }); + }); + // TODO See: https://github.com/microsoft/typespec/issues/2695 it.skip("emit diagnostic when unversioned op based on a template has a versioned model as a parameter", async () => { const diagnostics = await runner.diagnose(`