fix: treat concise arrow function bodies as implicit returns when calculating blockers (#18613)

Fixes #18612.

A concise arrow body does not contain a `ReturnStatement` which we traverse in full calculate_blockers (else we bail on functions), so short-cut to `touch` there.


---------

Co-authored-by: Simon Holthausen <simon.holthausen@vercel.com>
pull/18537/merge
Magnar Ovedal Myrtveit 4 days ago committed by GitHub
parent a4c60ccdbb
commit a166761b04
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: treat concise arrow function bodies as implicit returns when calculating blockers

@ -1235,12 +1235,15 @@ function calculate_blockers(instance, analysis) {
? /** @type {ESTree.FunctionExpression | ESTree.ArrowFunctionExpression} */ (fn.init)
: fn;
trace_references(
init.body,
reads_writes,
reads_writes,
/** @type {Scope} */ (instance.scopes.get(init))
);
const fn_scope = /** @type {Scope} */ (instance.scopes.get(init));
if (init.body.type === 'BlockStatement') {
trace_references(init.body, reads_writes, reads_writes, fn_scope);
} else {
// A concise arrow body is an implicit return, so treat it like the
// `ReturnStatement` visitor in `trace_references` would.
touch(init.body, fn_scope, reads_writes);
}
const max = [...reads_writes].reduce((max, binding) => {
if (binding.blocker) {

@ -3,12 +3,12 @@ import { test } from '../../test';
export default test({
mode: ['async-server', 'client', 'hydrate'],
ssrHtml: 'true true true true true',
ssrHtml: 'true true true true true true',
async test({ assert, target }) {
await new Promise((resolve) => setTimeout(resolve, 10));
await tick();
assert.htmlEqual(target.innerHTML, 'true true true true true');
assert.htmlEqual(target.innerHTML, 'true true true true true true');
}
});

@ -21,6 +21,8 @@
const indirect = () => checkedFactory()();
return indirect;
}
const arrow = () => () => checked;
</script>
<!-- force into separate effects -->
@ -39,3 +41,6 @@
{#if true}
{indirectChecked2()()}
{/if}
{#if true}
{arrow()()}
{/if}

Loading…
Cancel
Save