diff --git a/src/compiler/compile/Component.ts b/src/compiler/compile/Component.ts index 5f06de8e215b..75def35915d8 100644 --- a/src/compiler/compile/Component.ts +++ b/src/compiler/compile/Component.ts @@ -836,7 +836,7 @@ export default class Component { }); } - warn_on_undefined_store_value_references(node, parent, scope) { + warn_on_undefined_store_value_references(node, parent, scope: Scope) { if ( node.type === 'LabeledStatement' && node.label.name === '$' && @@ -852,8 +852,17 @@ export default class Component { const object = get_object(node); const { name } = object; - if (name[0] === '$' && !scope.has(name)) { - this.warn_if_undefined(name, object, null); + if (name[0] === '$') { + if (!scope.has(name)) { + this.warn_if_undefined(name, object, null); + } + + if (scope.find_owner(name.slice(1)) !== this.instance_scope) { + this.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)` + }); + } } } } diff --git a/test/runtime/samples/store-shadow-scope/_config.js b/test/runtime/samples/store-shadow-scope/_config.js new file mode 100644 index 000000000000..6b5f1a65588d --- /dev/null +++ b/test/runtime/samples/store-shadow-scope/_config.js @@ -0,0 +1,4 @@ +export default { + error: `Stores must be declared at the top level of the component (this may change in a future version of Svelte)`, + solo: true, +}; diff --git a/test/runtime/samples/store-shadow-scope/main.svelte b/test/runtime/samples/store-shadow-scope/main.svelte new file mode 100644 index 000000000000..72c4a06c2adc --- /dev/null +++ b/test/runtime/samples/store-shadow-scope/main.svelte @@ -0,0 +1,9 @@ +