From ac7c7646bcee53870dd96e9174728ffa1d63411d Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Thu, 8 Jan 2026 09:10:13 -0500 Subject: [PATCH] fix: don't transform references of function declarations in legacy mode (#17431) --- .changeset/better-games-invite.md | 5 +++++ .../svelte/src/compiler/phases/2-analyze/index.js | 3 ++- .../compiler/phases/2-analyze/visitors/EachBlock.js | 4 +++- .../samples/binding-indirect-fn/_config.js | 7 +++++++ .../samples/binding-indirect-fn/main.svelte | 11 +++++++++++ 5 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 .changeset/better-games-invite.md create mode 100644 packages/svelte/tests/runtime-legacy/samples/binding-indirect-fn/_config.js create mode 100644 packages/svelte/tests/runtime-legacy/samples/binding-indirect-fn/main.svelte diff --git a/.changeset/better-games-invite.md b/.changeset/better-games-invite.md new file mode 100644 index 0000000000..8361a1e9bb --- /dev/null +++ b/.changeset/better-games-invite.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: don't transform references of function declarations in legacy mode diff --git a/packages/svelte/src/compiler/phases/2-analyze/index.js b/packages/svelte/src/compiler/phases/2-analyze/index.js index 6d23e4d265..ef0b35f560 100644 --- a/packages/svelte/src/compiler/phases/2-analyze/index.js +++ b/packages/svelte/src/compiler/phases/2-analyze/index.js @@ -657,7 +657,8 @@ export function analyze_component(root, source, options) { if ( binding && binding.kind === 'normal' && - binding.declaration_kind !== 'import' + binding.declaration_kind !== 'import' && + binding.declaration_kind !== 'function' ) { binding.kind = 'state'; binding.mutated = true; diff --git a/packages/svelte/src/compiler/phases/2-analyze/visitors/EachBlock.js b/packages/svelte/src/compiler/phases/2-analyze/visitors/EachBlock.js index 81a9c1e2d1..5681966475 100644 --- a/packages/svelte/src/compiler/phases/2-analyze/visitors/EachBlock.js +++ b/packages/svelte/src/compiler/phases/2-analyze/visitors/EachBlock.js @@ -54,7 +54,9 @@ export function EachBlock(node, context) { // collect transitive dependencies... for (const binding of node.metadata.expression.dependencies) { - collect_transitive_dependencies(binding, node.metadata.transitive_deps); + if (binding.declaration_kind !== 'function') { + collect_transitive_dependencies(binding, node.metadata.transitive_deps); + } } // ...and ensure they are marked as state, so they can be turned diff --git a/packages/svelte/tests/runtime-legacy/samples/binding-indirect-fn/_config.js b/packages/svelte/tests/runtime-legacy/samples/binding-indirect-fn/_config.js new file mode 100644 index 0000000000..f17a7f4825 --- /dev/null +++ b/packages/svelte/tests/runtime-legacy/samples/binding-indirect-fn/_config.js @@ -0,0 +1,7 @@ +import { test } from '../../test'; + +export default test({ + async test({ assert, target }) { + assert.htmlEqual(target.innerHTML, ``); + } +}); diff --git a/packages/svelte/tests/runtime-legacy/samples/binding-indirect-fn/main.svelte b/packages/svelte/tests/runtime-legacy/samples/binding-indirect-fn/main.svelte new file mode 100644 index 0000000000..9c1e23a0f4 --- /dev/null +++ b/packages/svelte/tests/runtime-legacy/samples/binding-indirect-fn/main.svelte @@ -0,0 +1,11 @@ + + +{#each items.filter(fn) as item} + +{/each}