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..a5df63547c --- /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": 2, + "column": 8 + }, + "end": { + "line": 2, + "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..800a3ae8d1 --- /dev/null +++ b/packages/svelte/tests/validator/samples/declaration-tag-snippet-parameter/input.svelte @@ -0,0 +1,6 @@ +{#snippet row(item)} + {const item = 1} +
{item}
+{/snippet} + +{@render row(5)} diff --git a/packages/svelte/tests/validator/samples/snippet-parameter-shadowed-in-block/errors.json b/packages/svelte/tests/validator/samples/snippet-parameter-shadowed-in-block/errors.json new file mode 100644 index 0000000000..fe51488c70 --- /dev/null +++ b/packages/svelte/tests/validator/samples/snippet-parameter-shadowed-in-block/errors.json @@ -0,0 +1 @@ +[] diff --git a/packages/svelte/tests/validator/samples/snippet-parameter-shadowed-in-block/input.svelte b/packages/svelte/tests/validator/samples/snippet-parameter-shadowed-in-block/input.svelte new file mode 100644 index 0000000000..90162859a1 --- /dev/null +++ b/packages/svelte/tests/validator/samples/snippet-parameter-shadowed-in-block/input.svelte @@ -0,0 +1,8 @@ +{#snippet row(item)} + {#if item} + {const item = 1} +{item}
+ {/if} +{/snippet} + +{@render row(5)}