diff --git a/.changeset/snippet-parameter-redeclared.md b/.changeset/snippet-parameter-redeclared.md new file mode 100644 index 0000000000..9bb14cf3af --- /dev/null +++ b/.changeset/snippet-parameter-redeclared.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: error at compile time when a declaration in a snippet redeclares one of its parameters diff --git a/packages/svelte/src/compiler/phases/scope.js b/packages/svelte/src/compiler/phases/scope.js index 77c9119364..0d8e570772 100644 --- a/packages/svelte/src/compiler/phases/scope.js +++ b/packages/svelte/src/compiler/phases/scope.js @@ -1343,6 +1343,14 @@ export function create_scopes(ast, root, allow_reactive_declarations, parent) { } context.next({ scope: child_scope }); + + // the parameters and what the body declares end up in the same function + const body_scope = /** @type {Scope} */ (scopes.get(node.body)); + for (const [name, binding] of body_scope.declarations) { + if (child_scope.declarations.has(name)) { + e.declaration_duplicate(binding.node, name); + } + } }, Fragment: (node, context) => { diff --git a/packages/svelte/tests/validator/samples/declaration-tag-snippet-parameter/errors.json b/packages/svelte/tests/validator/samples/declaration-tag-snippet-parameter/errors.json new file mode 100644 index 0000000000..45e51d5f01 --- /dev/null +++ b/packages/svelte/tests/validator/samples/declaration-tag-snippet-parameter/errors.json @@ -0,0 +1,14 @@ +[ + { + "code": "declaration_duplicate", + "message": "`item` has already been declared", + "start": { + "line": 13, + "column": 8 + }, + "end": { + "line": 13, + "column": 12 + } + } +] diff --git a/packages/svelte/tests/validator/samples/declaration-tag-snippet-parameter/input.svelte b/packages/svelte/tests/validator/samples/declaration-tag-snippet-parameter/input.svelte new file mode 100644 index 0000000000..b59496dda1 --- /dev/null +++ b/packages/svelte/tests/validator/samples/declaration-tag-snippet-parameter/input.svelte @@ -0,0 +1,17 @@ + +{#snippet row1(item)} +{#if item} +{const item = 1} +

{item}

+{/if} +{/snippet} + +{@render row1(5)} + + +{#snippet row2(item)} + {const item = 1} +

{item}

+{/snippet} + +{@render row2(5)}