diff --git a/.changeset/thick-dryers-kiss.md b/.changeset/thick-dryers-kiss.md new file mode 100644 index 0000000000..bbdc765b4e --- /dev/null +++ b/.changeset/thick-dryers-kiss.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: don't emit assignment warnings for bindings diff --git a/packages/svelte/src/compiler/phases/3-transform/client/visitors/AssignmentExpression.js b/packages/svelte/src/compiler/phases/3-transform/client/visitors/AssignmentExpression.js index 66ea2c4941..5ac33e629e 100644 --- a/packages/svelte/src/compiler/phases/3-transform/client/visitors/AssignmentExpression.js +++ b/packages/svelte/src/compiler/phases/3-transform/client/visitors/AssignmentExpression.js @@ -169,6 +169,17 @@ function build_assignment(operator, left, right, context) { } } + // special case — ignore `bind:prop={getter, (v) => (...)}` / `bind:value={x.y}` + if ( + path.at(-1) === 'Component' || + path.at(-1) === 'SvelteComponent' || + (path.at(-1) === 'ArrowFunctionExpression' && + path.at(-2) === 'SequenceExpression' && + (path.at(-3) === 'Component' || path.at(-3) === 'SvelteComponent')) + ) { + should_transform = false; + } + if (left.type === 'MemberExpression' && should_transform) { const callee = callees[operator]; diff --git a/packages/svelte/src/internal/client/dev/assign.js b/packages/svelte/src/internal/client/dev/assign.js index cf8c31a941..fc1b647f78 100644 --- a/packages/svelte/src/internal/client/dev/assign.js +++ b/packages/svelte/src/internal/client/dev/assign.js @@ -1,3 +1,4 @@ +import { untrack } from '../runtime.js'; import * as w from '../warnings.js'; import { sanitize_location } from './location.js'; @@ -23,7 +24,12 @@ function compare(a, b, property, location) { * @param {string} location */ export function assign(object, property, value, location) { - return compare((object[property] = value), object[property], property, location); + return compare( + (object[property] = value), + untrack(() => object[property]), + property, + location + ); } /** @@ -33,7 +39,12 @@ export function assign(object, property, value, location) { * @param {string} location */ export function assign_and(object, property, value, location) { - return compare((object[property] &&= value), object[property], property, location); + return compare( + (object[property] &&= value), + untrack(() => object[property]), + property, + location + ); } /** @@ -43,7 +54,12 @@ export function assign_and(object, property, value, location) { * @param {string} location */ export function assign_or(object, property, value, location) { - return compare((object[property] ||= value), object[property], property, location); + return compare( + (object[property] ||= value), + untrack(() => object[property]), + property, + location + ); } /** @@ -53,5 +69,10 @@ export function assign_or(object, property, value, location) { * @param {string} location */ export function assign_nullish(object, property, value, location) { - return compare((object[property] ??= value), object[property], property, location); + return compare( + (object[property] ??= value), + untrack(() => object[property]), + property, + location + ); } diff --git a/packages/svelte/tests/runtime-runes/samples/proxy-coercive-assignment-warning/Test.svelte b/packages/svelte/tests/runtime-runes/samples/proxy-coercive-assignment-warning/Test.svelte new file mode 100644 index 0000000000..c2b06202ae --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/proxy-coercive-assignment-warning/Test.svelte @@ -0,0 +1,11 @@ + diff --git a/packages/svelte/tests/runtime-runes/samples/proxy-nullish-coalescing-assignment-warning/_config.js b/packages/svelte/tests/runtime-runes/samples/proxy-coercive-assignment-warning/_config.js similarity index 79% rename from packages/svelte/tests/runtime-runes/samples/proxy-nullish-coalescing-assignment-warning/_config.js rename to packages/svelte/tests/runtime-runes/samples/proxy-coercive-assignment-warning/_config.js index a6d79c05ed..ad7bdc654a 100644 --- a/packages/svelte/tests/runtime-runes/samples/proxy-nullish-coalescing-assignment-warning/_config.js +++ b/packages/svelte/tests/runtime-runes/samples/proxy-coercive-assignment-warning/_config.js @@ -6,19 +6,19 @@ export default test({ dev: true }, - html: ``, + html: `
x
`, test({ assert, target, warnings }) { const btn = target.querySelector('button'); flushSync(() => btn?.click()); - assert.htmlEqual(target.innerHTML, ``); + assert.htmlEqual(target.innerHTML, `
x
`); flushSync(() => btn?.click()); - assert.htmlEqual(target.innerHTML, ``); + assert.htmlEqual(target.innerHTML, `
x
`); assert.deepEqual(warnings, [ - 'Assignment to `items` property (main.svelte:5:24) will evaluate to the right-hand side, not the value of `items` following the assignment. This may result in unexpected behaviour.' + 'Assignment to `items` property (main.svelte:8:24) will evaluate to the right-hand side, not the value of `items` following the assignment. This may result in unexpected behaviour.' ]); } }); diff --git a/packages/svelte/tests/runtime-runes/samples/proxy-coercive-assignment-warning/main.svelte b/packages/svelte/tests/runtime-runes/samples/proxy-coercive-assignment-warning/main.svelte new file mode 100644 index 0000000000..40592e08b8 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/proxy-coercive-assignment-warning/main.svelte @@ -0,0 +1,16 @@ + + + + + +
x
+ + entries[2], (v) => (entries[2] = v)}> + diff --git a/packages/svelte/tests/runtime-runes/samples/proxy-nullish-coalescing-assignment/_config.js b/packages/svelte/tests/runtime-runes/samples/proxy-coercive-assignment/_config.js similarity index 86% rename from packages/svelte/tests/runtime-runes/samples/proxy-nullish-coalescing-assignment/_config.js rename to packages/svelte/tests/runtime-runes/samples/proxy-coercive-assignment/_config.js index 99d957e980..1603241227 100644 --- a/packages/svelte/tests/runtime-runes/samples/proxy-nullish-coalescing-assignment/_config.js +++ b/packages/svelte/tests/runtime-runes/samples/proxy-coercive-assignment/_config.js @@ -5,7 +5,7 @@ export default test({ html: ``, test({ assert, target }) { - const [btn1, btn2] = target.querySelectorAll('button'); + const [btn1] = target.querySelectorAll('button'); flushSync(() => btn1.click()); assert.htmlEqual(target.innerHTML, ``); diff --git a/packages/svelte/tests/runtime-runes/samples/proxy-nullish-coalescing-assignment/main.svelte b/packages/svelte/tests/runtime-runes/samples/proxy-coercive-assignment/main.svelte similarity index 100% rename from packages/svelte/tests/runtime-runes/samples/proxy-nullish-coalescing-assignment/main.svelte rename to packages/svelte/tests/runtime-runes/samples/proxy-coercive-assignment/main.svelte diff --git a/packages/svelte/tests/runtime-runes/samples/proxy-nullish-coalescing-assignment-warning/main.svelte b/packages/svelte/tests/runtime-runes/samples/proxy-nullish-coalescing-assignment-warning/main.svelte deleted file mode 100644 index f151336046..0000000000 --- a/packages/svelte/tests/runtime-runes/samples/proxy-nullish-coalescing-assignment-warning/main.svelte +++ /dev/null @@ -1,7 +0,0 @@ - - -