diff --git a/src/compile/nodes/shared/Expression.ts b/src/compile/nodes/shared/Expression.ts
index 818066f21aaf..a4281eac641e 100644
--- a/src/compile/nodes/shared/Expression.ts
+++ b/src/compile/nodes/shared/Expression.ts
@@ -122,8 +122,16 @@ export default class Expression {
const { name, nodes } = flattenReference(node);
if (scope.has(name)) return;
+
if (globalWhitelist.has(name) && !component.var_lookup.has(name)) return;
+ if (name[0] === '$' && template_scope.names.has(name.slice(1))) {
+ component.error(node, {
+ code: `contextual-store`,
+ message: `Stores must be declared at the top level of the component (this may change in a future version of Svelte)`
+ });
+ }
+
if (template_scope.is_let(name)) {
if (!function_expression) {
dependencies.add(name);
diff --git a/test/runtime/samples/store-contextual/_config.js b/test/runtime/samples/store-contextual/_config.js
new file mode 100644
index 000000000000..c759ede650ff
--- /dev/null
+++ b/test/runtime/samples/store-contextual/_config.js
@@ -0,0 +1,76 @@
+import { writable } from '../../../../store.js';
+
+const todos = [
+ writable({ done: false, text: 'write docs' }),
+ writable({ done: false, text: 'implement contextual stores' }),
+ writable({ done: false, text: 'go outside' })
+];
+
+export default {
+ error: `Stores must be declared at the top level of the component (this may change in a future version of Svelte)`,
+
+ props: {
+ todos
+ },
+
+ html: `
+
+
+
+
+
+ `,
+
+ async test({ assert, component, target, window }) {
+ const inputs = target.querySelectorAll('input');
+ const change = new window.MouseEvent('change');
+
+ inputs[1].checked = true;
+ await inputs[1].dispatchEvent(change);
+
+ assert.htmlEqual(target.innerHTML, `
+
+
+
+
+
+ `);
+
+ await todos[0].update(todo => ({ done: !todo.done, text: todo.text }));
+
+ assert.htmlEqual(target.innerHTML, `
+
+
+
+
+
+ `);
+ }
+};
\ No newline at end of file
diff --git a/test/runtime/samples/store-contextual/main.svelte b/test/runtime/samples/store-contextual/main.svelte
new file mode 100644
index 000000000000..f8403eded480
--- /dev/null
+++ b/test/runtime/samples/store-contextual/main.svelte
@@ -0,0 +1,6 @@
+{#each todos as todo}
+
+{/each}
\ No newline at end of file