From 0e0f01ee1cfe11461f799c034030840a1b7cd763 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Mon, 27 Jan 2025 08:13:13 -0500 Subject: [PATCH] fix: disallow $state/$derived in const tags (#15115) --- .changeset/strong-shoes-whisper.md | 5 +++++ .../phases/2-analyze/visitors/CallExpression.js | 3 ++- .../const-tag-invalid-rune-usage/errors.json | 14 ++++++++++++++ .../const-tag-invalid-rune-usage/input.svelte | 3 +++ 4 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 .changeset/strong-shoes-whisper.md create mode 100644 packages/svelte/tests/validator/samples/const-tag-invalid-rune-usage/errors.json create mode 100644 packages/svelte/tests/validator/samples/const-tag-invalid-rune-usage/input.svelte diff --git a/.changeset/strong-shoes-whisper.md b/.changeset/strong-shoes-whisper.md new file mode 100644 index 0000000000..ea7f8d6c5e --- /dev/null +++ b/.changeset/strong-shoes-whisper.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: disallow $state/$derived in const tags diff --git a/packages/svelte/src/compiler/phases/2-analyze/visitors/CallExpression.js b/packages/svelte/src/compiler/phases/2-analyze/visitors/CallExpression.js index 96788d9f93..0a6b3f3ee5 100644 --- a/packages/svelte/src/compiler/phases/2-analyze/visitors/CallExpression.js +++ b/packages/svelte/src/compiler/phases/2-analyze/visitors/CallExpression.js @@ -79,7 +79,8 @@ export function CallExpression(node, context) { case '$derived': case '$derived.by': if ( - parent.type !== 'VariableDeclarator' && + (parent.type !== 'VariableDeclarator' || + get_parent(context.path, -3).type === 'ConstTag') && !(parent.type === 'PropertyDefinition' && !parent.static && !parent.computed) ) { e.state_invalid_placement(node, rune); diff --git a/packages/svelte/tests/validator/samples/const-tag-invalid-rune-usage/errors.json b/packages/svelte/tests/validator/samples/const-tag-invalid-rune-usage/errors.json new file mode 100644 index 0000000000..32594e4268 --- /dev/null +++ b/packages/svelte/tests/validator/samples/const-tag-invalid-rune-usage/errors.json @@ -0,0 +1,14 @@ +[ + { + "code": "state_invalid_placement", + "message": "`$derived(...)` can only be used as a variable declaration initializer or a class field", + "start": { + "line": 2, + "column": 15 + }, + "end": { + "line": 2, + "column": 26 + } + } +] diff --git a/packages/svelte/tests/validator/samples/const-tag-invalid-rune-usage/input.svelte b/packages/svelte/tests/validator/samples/const-tag-invalid-rune-usage/input.svelte new file mode 100644 index 0000000000..a056058cc5 --- /dev/null +++ b/packages/svelte/tests/validator/samples/const-tag-invalid-rune-usage/input.svelte @@ -0,0 +1,3 @@ +{#snippet test()} + {@const der = $derived(0)} +{/snippet} \ No newline at end of file