diff --git a/.changeset/hip-oranges-hang.md b/.changeset/hip-oranges-hang.md new file mode 100644 index 0000000000..addbeafa9c --- /dev/null +++ b/.changeset/hip-oranges-hang.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: disallow `bind:group` to snippet parameters diff --git a/documentation/docs/98-reference/.generated/compile-errors.md b/documentation/docs/98-reference/.generated/compile-errors.md index a4ecbb31d5..ea116014e7 100644 --- a/documentation/docs/98-reference/.generated/compile-errors.md +++ b/documentation/docs/98-reference/.generated/compile-errors.md @@ -84,6 +84,12 @@ Attribute values containing `{...}` must be enclosed in quote marks, unless the `bind:group` can only bind to an Identifier or MemberExpression ``` +### bind_group_invalid_snippet_parameter + +``` +Cannot `bind:group` to a snippet parameter +``` + ### bind_invalid_expression ``` diff --git a/packages/svelte/messages/compile-errors/template.md b/packages/svelte/messages/compile-errors/template.md index d061416dbd..0569f63ad3 100644 --- a/packages/svelte/messages/compile-errors/template.md +++ b/packages/svelte/messages/compile-errors/template.md @@ -54,6 +54,10 @@ > `bind:group` can only bind to an Identifier or MemberExpression +## bind_group_invalid_snippet_parameter + +> Cannot `bind:group` to a snippet parameter + ## bind_invalid_expression > Can only bind to an Identifier or MemberExpression or a `{get, set}` pair diff --git a/packages/svelte/src/compiler/errors.js b/packages/svelte/src/compiler/errors.js index 93eeee539c..677b99fcff 100644 --- a/packages/svelte/src/compiler/errors.js +++ b/packages/svelte/src/compiler/errors.js @@ -752,6 +752,15 @@ export function bind_group_invalid_expression(node) { e(node, 'bind_group_invalid_expression', `\`bind:group\` can only bind to an Identifier or MemberExpression\nhttps://svelte.dev/e/bind_group_invalid_expression`); } +/** + * Cannot `bind:group` to a snippet parameter + * @param {null | number | NodeLike} node + * @returns {never} + */ +export function bind_group_invalid_snippet_parameter(node) { + e(node, 'bind_group_invalid_snippet_parameter', `Cannot \`bind:group\` to a snippet parameter\nhttps://svelte.dev/e/bind_group_invalid_snippet_parameter`); +} + /** * Can only bind to an Identifier or MemberExpression or a `{get, set}` pair * @param {null | number | NodeLike} node diff --git a/packages/svelte/src/compiler/phases/2-analyze/visitors/BindDirective.js b/packages/svelte/src/compiler/phases/2-analyze/visitors/BindDirective.js index 509fecf301..18ea79262b 100644 --- a/packages/svelte/src/compiler/phases/2-analyze/visitors/BindDirective.js +++ b/packages/svelte/src/compiler/phases/2-analyze/visitors/BindDirective.js @@ -191,6 +191,10 @@ export function BindDirective(node, context) { throw new Error('Cannot find declaration for bind:group'); } + if (binding.kind === 'snippet') { + e.bind_group_invalid_snippet_parameter(node); + } + // Traverse the path upwards and find all EachBlocks who are (indirectly) contributing to bind:group, // i.e. one of their declarations is referenced in the binding. This allows group bindings to work // correctly when referencing a variable declared in an EachBlock by using the index of the each block diff --git a/packages/svelte/tests/validator/samples/bind-group-snippet-parameter/errors.json b/packages/svelte/tests/validator/samples/bind-group-snippet-parameter/errors.json new file mode 100644 index 0000000000..15e762419f --- /dev/null +++ b/packages/svelte/tests/validator/samples/bind-group-snippet-parameter/errors.json @@ -0,0 +1,14 @@ +[ + { + "code": "bind_group_invalid_snippet_parameter", + "end": { + "column": 44, + "line": 2 + }, + "message": "Cannot `bind:group` to a snippet parameter", + "start": { + "column": 21, + "line": 2 + } + } +] diff --git a/packages/svelte/tests/validator/samples/bind-group-snippet-parameter/input.svelte b/packages/svelte/tests/validator/samples/bind-group-snippet-parameter/input.svelte new file mode 100644 index 0000000000..368484788a --- /dev/null +++ b/packages/svelte/tests/validator/samples/bind-group-snippet-parameter/input.svelte @@ -0,0 +1,3 @@ +{#snippet test(group)} + +{/snippet} \ No newline at end of file