XUO/SWE-PolyBench huggingface dataset:
Repository: sveltejs/svelte (JavaScript) — Bug Fix

Issue:
Assigning to a member expression in a reactive statement shouldn't auto-declare the variable
**Describe the bug**
A reactive assignment that looks like `$: document.title = whatever;` doesn't work, because the compiler (unhelpfully, in this case) auto-declares `document` for us, and - since that is now undefined - the assignment `document.title = whatever;` is a runtime error.

**Logs**
`TypeError: document is undefined`

**To Reproduce**
```svelte
<script>
  $: document.title = 'foo';
</script>
```

**Expected behavior**
This should simply assign to the global `document` and not attempt to automatically declare it

**Stacktraces**
-

**Information about your Svelte project:**
Svelte 3.16.7 - independent of browser or bundler.

**Severity**
Moderate, probably. We do specifically mention this syntax in the docs, and it doesn't work.

**Additional context**
I believe this will simply be a matter of adjusting the logic [here](https://github.com/sveltejs/svelte/blob/5486d67adf2d48820e94a1812028dba9392975b7/src/compiler/compile/Component.ts#L600
) for when we bail out and decide we don't need to auto-declare the variable.


Discussion:

Resolving patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,7 @@
 
 * Prevent text input cursor jumping in Safari with one-way binding ([#3449](https://github.com/sveltejs/svelte/issues/3449))
 * Expose compiler version in dev events ([#4047](https://github.com/sveltejs/svelte/issues/4047))
+* Do not automatically declare variables in reactive declarations when assigning to a member expression ([#4212](https://github.com/sveltejs/svelte/issues/4212))
 
 ## 3.16.7
 
diff --git a/src/compiler/compile/Component.ts b/src/compiler/compile/Component.ts
--- a/src/compiler/compile/Component.ts
+++ b/src/compiler/compile/Component.ts
@@ -603,6 +603,7 @@ export default class Component {
 
 			const { expression } = node.body;
 			if (expression.type !== 'AssignmentExpression') return;
+			if (expression.left.type === 'MemberExpression') return;
 
 			extract_names(expression.left).forEach(name => {
 				if (!this.var_lookup.has(name) && name[0] !== '$') {


Test patch:
diff --git a/test/runtime/samples/reactive-values-no-implicit-member-expression/_config.js b/test/runtime/samples/reactive-values-no-implicit-member-expression/_config.js
new file mode 100644
--- /dev/null
+++ b/test/runtime/samples/reactive-values-no-implicit-member-expression/_config.js
@@ -0,0 +1,5 @@
+export default {
+	test({ assert, window }) {
+		assert.equal(window.document.title, 'foo');
+	}
+};
diff --git a/test/runtime/samples/reactive-values-no-implicit-member-expression/main.svelte b/test/runtime/samples/reactive-values-no-implicit-member-expression/main.svelte
new file mode 100644
--- /dev/null
+++ b/test/runtime/samples/reactive-values-no-implicit-member-expression/main.svelte
@@ -0,0 +1,3 @@
+<script>
+	$: document.title = 'foo';
+</script>
Repository: sveltejs/svelte (JavaScript) — Bug Fix

Issue:
Dev mode {#each} check breaks with strings
**Describe the bug**
The dev mode validation check for `{#each}` blocks breaks with strings.

**Logs**
`cannot use 'in' operator to search for "length" in "foo"`

**To Reproduce**
https://svelte.dev/repl/svg-transitions?version=3.19.0

**Expected behavior**
Same as https://svelte.dev/repl/svg-transitions?version=3.18.2

**Stacktraces**
-

**Information about your Svelte project:**
- Browser independent
- Reproducible in REPL

**Severity**
Moderate, probably.

**Additional context**
The check introduced in #4419 apparently throws with strings. We probably want to consider strings to be array-like objects, and so we need to be more permissive with the validation check.


Discussion:

Resolving patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,9 @@
 # Svelte changelog
 
+## Unreleased
+
+* Fix dev mode validation of `{#each}` blocks using strings ([#4450](https://github.com/sveltejs/svelte/issues/4450))
+
 ## 3.19.0
 
 * Fix indirect bindings involving elements with spreads ([#3680](https://github.com/sveltejs/svelte/issues/3680))
diff --git a/src/runtime/internal/dev.ts b/src/runtime/internal/dev.ts
--- a/src/runtime/internal/dev.ts
+++ b/src/runtime/internal/dev.ts
@@ -80,7 +80,7 @@ export function set_data_dev(text, data) {
 }
 
 export function validate_each_argument(arg) {
-	if (!arg || !('length' in arg)) {
+	if (typeof arg !== 'string' && !(arg && typeof arg === 'object' && 'length' in arg)) {
 		let msg = '{#each} only iterates over array-like objects.';
 		if (typeof Symbol === 'function' && arg && Symbol.iterator in arg) {
 			msg += ' You can use a spread to convert this iterable into an array.';


Test patch:
diff --git a/test/runtime/samples/each-block-string/_config.js b/test/runtime/samples/each-block-string/_config.js
new file mode 100644
--- /dev/null
+++ b/test/runtime/samples/each-block-string/_config.js
@@ -0,0 +1,10 @@
+export default {
+	compileOptions: {
+		dev: true
+	},
+	html: `
+		<div>f</div>
+		<div>o</div>
+		<div>o</div>
+	`
+};
diff --git a/test/runtime/samples/each-block-string/main.svelte b/test/runtime/samples/each-block-string/main.svelte
new file mode 100644
--- /dev/null
+++ b/test/runtime/samples/each-block-string/main.svelte
@@ -0,0 +1,3 @@
+{#each 'foo' as c}
+	<div>{c}</div>
+{/each}
Repository: sveltejs/svelte (JavaScript) — Bug Fix

Issue:
If blocks in nested slots break the app
**Description**
When using an if-block directly in a nested slot, it causes the app to break. 

**To Reproduce**
- Open REPL: https://svelte.dev/repl/b78f73d066784716806a64d86a0ed58a?version=3.20.1
- Simply open the console and click the checkbox.

<details>
  <summary>Stack trace</summary>

VM260:541 Uncaught (in promise) ReferenceError: span is not defined
    at Object.update [as p] (eval at handle_message (VM254 about:srcdoc:13), <anonymous>:541:21)
    at Object.update [as p] (eval at handle_message (VM254 about:srcdoc:13), <anonymous>:597:35)
    at Object.update [as p] (eval at handle_message (VM254 about:srcdoc:13), <anonymous>:428:21)
    at update (eval at handle_message (VM254 about:srcdoc:13), <anonymous>:167:40)
    at flush (eval at handle_message (VM254 about:srcdoc:13), <anonymous>:136:17)

</details>


**Information about your Svelte project:**
- Your browser and the version: Chrome (latest)
- OS X 

**Severity**
Hard to judge. On the one hand, it breaks the app. But on the other hand, there is a straightforward workaround, so it can be easily mitigated: As soon as the if-block is contained in another element it works: https://svelte.dev/repl/803509fd37d3464c879e2af530db7ba1?version=3.20.1

**Will break:**
```svelte
<Inner>
	<span slot="label">
		<slot>
			Click on the checkbox to break the app
			{#if showMore}
				more
			{/if}
		</slot>
	</span>
</Inner>
```

**Will work:**
```svelte
<Inner>
	<span slot="label">
		<slot>
			<span>
				This one will not break
				{#if showMore}
					more
				{/if}
			</span>
		</slot>
	</span>
</Inner>
```


Discussion:

Resolving patch:
diff --git a/src/compiler/compile/render_dom/wrappers/Slot.ts b/src/compiler/compile/render_dom/wrappers/Slot.ts
--- a/src/compiler/compile/render_dom/wrappers/Slot.ts
+++ b/src/compiler/compile/render_dom/wrappers/Slot.ts
@@ -45,7 +45,7 @@ export default class SlotWrapper extends Wrapper {
 			renderer,
 			this.fallback,
 			node.children,
-			parent,
+			this,
 			strip_whitespace,
 			next_sibling
 		);


Test patch:
diff --git a/test/runtime/samples/slot-if-block-update-no-anchor/_config.js b/test/runtime/samples/slot-if-block-update-no-anchor/_config.js
new file mode 100644
--- /dev/null
+++ b/test/runtime/samples/slot-if-block-update-no-anchor/_config.js
@@ -0,0 +1,7 @@
+export default {
+	test({ assert, target, component }) {
+		assert.htmlEqual(target.innerHTML, `<span></span>`);
+		component.enabled = true;
+		assert.htmlEqual(target.innerHTML, `<span>enabled</span>`);
+	},
+};
diff --git a/test/runtime/samples/slot-if-block-update-no-anchor/main.svelte b/test/runtime/samples/slot-if-block-update-no-anchor/main.svelte
new file mode 100644
--- /dev/null
+++ b/test/runtime/samples/slot-if-block-update-no-anchor/main.svelte
@@ -0,0 +1,9 @@
+<script>
+	export let enabled = false;
+</script>
+
+<span>
+	<slot>
+		{#if enabled}enabled{/if}
+	</slot>
+</span>
Repository: sveltejs/svelte (JavaScript) — Bug Fix

Issue:
Immediate tweened store value update with { duration: 0 } option
**Is your feature request related to a problem? Please describe.**
In Firefox and Safari, when there's a tweened store and we call `tweenedStore.update(fn, {duration: 0})` sometimes the tweened value gets computed to `NaN`. Then I went to read about how the value gets computed: 
https://github.com/sveltejs/svelte/blob/master/src/runtime/motion/tweened.ts#L121
As the result is based on `elapsed/duration`, which makes sense to not have duration to be 0 mathematically. Although, in FF and Safari the `elapsed` variable can be `0` when compute is getting executed, which causes the result of the compute to be NaN.

**Describe the solution you'd like**
if the `options.duration` is 0 then we set the value right away instead of going through the interpolation compute ?

**Describe alternatives you've considered**

- We can clamp the lower bound duration to 1, just in case another person runs into situation like this
- error on passing `options.duration` when <=0

**How important is this feature to you?**
Currently I'm using `{duration: 1}` as a work around. when I want to update some tweened store "immediately". I'm curious about what would be a good way to handle this tho !

**Additional context**
Thanks for reading !



Discussion:
I'd prefer to early-out and immediately set the value in this case as well.
I bumped into this issue while implementing touch gestures for an image gallery. I wanted to set the value immediately when handling touch events, but have the possibility to tween/spring the values when, for example, the user's gesture moved something a bit too far and I need to revert state to the nearest sensible value.

Resolving patch:
diff --git a/src/runtime/motion/tweened.ts b/src/runtime/motion/tweened.ts
--- a/src/runtime/motion/tweened.ts
+++ b/src/runtime/motion/tweened.ts
@@ -93,6 +93,11 @@ export function tweened<T>(value?: T, defaults: Options<T> = {}): Tweened<T> {
 			interpolate = get_interpolator
 		} = assign(assign({}, defaults), opts);
 
+		if (duration === 0) {
+			store.set(target_value);
+			return Promise.resolve();
+		}
+
 		const start = now() + delay;
 		let fn;
 


Test patch:
diff --git a/test/motion/index.js b/test/motion/index.js
--- a/test/motion/index.js
+++ b/test/motion/index.js
@@ -19,5 +19,12 @@ describe('motion', () => {
 			size.set(100);
 			assert.equal(get(size), 100);
 		});
+
+		it('sets immediately when duration is 0', () => {
+			const size = tweened(0);
+
+			size.set(100, { duration : 0 });
+			assert.equal(get(size), 100);
+		});
 	});
 });
Repository: sveltejs/svelte (JavaScript) — Bug Fix

Issue:
img-redundant-alt warning bug (Breaking)
**Describe the bug**
`alt` attributes with expressions on image elements returns `null` for static value, but new commit for `img-redundant-alt` warning checks it as a string. 

https://github.com/sveltejs/svelte/commit/153b128fe28a3283b684fccb051deb66152a6d46#diff-8e6b4a7e9c9ba91db066af615305f5f4R491

This breaks whole build process.

**Logs**
Build log:
```
[!] (plugin svelte) TypeError: Cannot read property 'match' of null
 src/components/SourcesBar.svelte
 TypeError: Cannot read property 'match' of null
     at Element$1.validate_special_cases (node_modules/svelte/src/compiler/compile/nodes/Element.ts:491:19)
     at Element$1.validate (node_modules/svelte/src/compiler/compile/nodes/Element.ts:275:8)
     at new Element$1 (node_modules/svelte/src/compiler/compile/nodes/Element.ts:220:8)
     ...
```

**To Reproduce**
https://svelte.dev/repl/1b24eb90a2bf4b1fbcbc1250b80aecbb?version=3.22.0

**Expected behavior**
Skip check if alt value is not string or falsy. (`null` in this case)

**Information about your Svelte project:**

- Tested on e.x. OS X 10.14, Ubuntu Linux 19.10

- Svelte version: 3.22.0 

- Whether your project uses Webpack or Rollup: Rollup

**Severity**
BREAKING!

**Additional context**
I'm sending PR soon!



Discussion:

Resolving patch:
diff --git a/src/compiler/compile/nodes/Element.ts b/src/compiler/compile/nodes/Element.ts
--- a/src/compiler/compile/nodes/Element.ts
+++ b/src/compiler/compile/nodes/Element.ts
@@ -438,7 +438,7 @@ export default class Element extends Node {
 
 			if (href_attribute) {
 				const href_value = href_attribute.get_static_value();
-				
+
 				if (href_value === '' || href_value === '#' || /^\W*javascript:/i.test(href_value)) {
 					component.warn(href_attribute, {
 						code: `a11y-invalid-attribute`,
@@ -484,11 +484,11 @@ export default class Element extends Node {
 			const aria_hidden_attribute = attribute_map.get('aria-hidden');
 
 			const aria_hidden_exist = aria_hidden_attribute && aria_hidden_attribute.get_static_value();
-			
+
 			if (alt_attribute && !aria_hidden_exist) {
 				const alt_value = alt_attribute.get_static_value();
 
-				if (alt_value.match(/\b(image|picture|photo)\b/i)) {
+				if (alt_value && alt_value.match(/\b(image|picture|photo)\b/i)) {
 					component.warn(this, {
 						code: `a11y-img-redundant-alt`,
 						message: `A11y: Screenreaders already announce <img> elements as an image.`


Test patch:
diff --git a/test/validator/samples/a11y-img-redundant-alt/input.svelte b/test/validator/samples/a11y-img-redundant-alt/input.svelte
--- a/test/validator/samples/a11y-img-redundant-alt/input.svelte
+++ b/test/validator/samples/a11y-img-redundant-alt/input.svelte
@@ -4,4 +4,5 @@
 <img src="bar" alt="Image of me at a bar!" />
 <img src="foo" alt="Picture of baz fixing a bug." />
 <img src="bar" alt="Plant doing photosynthesis in the afternoon" />
-<img src="foo" alt="Picturesque food" />
\ No newline at end of file
+<img src="foo" alt="Picturesque food" />
+<img src="baz" alt={'baz'} />
Repository: sveltejs/svelte (JavaScript) — Bug Fix

Issue:
For input numbers we should use null instead undefined in toNumber
If you return undefined it became the problem for some situations like this (we can't set undefined back):
https://svelte.technology/repl?version=2.30.1&gist=4728f0fd73979c92e7c07ec0a7eebb94

by the standard, the "number input" can contain numbers or empty and empty here is an empty string or null. 
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/number


Discussion:
I don't know what the problem was supposed to have been when this issue was opened (and I also don't know what version it was against. there is no 2.30.1), but in the latest v2 I don't see anything in the console https://v2.svelte.dev/repl?version=2.16.1&gist=4728f0fd73979c92e7c07ec0a7eebb94
@Conduitry 
this problem still exists, I can reproduce it even on v3 https://svelte.dev/repl/922cb0532c56400a94d95e8d4536e322?version=3.8.0

please reopen. The main idea is you can't return undefined from "input number" because you can't set it back, it's just not valid by the standard. 
Returning `undefined` for an empty number input field happened in #606 as a solution for #584. I don't know what returning `null` instead would do.
I see, anyway return `null` also should fix #584 and will be consistent with browsers standards. 
(and fix browsers warnings)
Warnings like this:
```
VM67:304 The specified value "undefined" is not a valid number. The value must match to the following regular expression: -?(\d+|\d+\.\d+|\.\d+)([eE][-+]?\d+)?
```
@Conduitry did you see the same warning? 
I see the warning in 3.20.1 - note that the warning doesn't appear in the Svelte console, but the browser console.

Resolving patch:
diff --git a/src/runtime/internal/dom.ts b/src/runtime/internal/dom.ts
--- a/src/runtime/internal/dom.ts
+++ b/src/runtime/internal/dom.ts
@@ -133,7 +133,7 @@ export function get_binding_group_value(group) {
 }
 
 export function to_number(value) {
-	return value === '' ? undefined : +value;
+	return value === '' ? null : +value;
 }
 
 export function time_ranges_to_array(ranges) {


Test patch:
diff --git a/test/runtime/samples/binding-input-number/_config.js b/test/runtime/samples/binding-input-number/_config.js
--- a/test/runtime/samples/binding-input-number/_config.js
+++ b/test/runtime/samples/binding-input-number/_config.js
@@ -35,14 +35,14 @@ export default {
 			<p>number 44</p>
 		`);
 
-		// empty string should be treated as undefined
+		// empty string should be treated as null
 		input.value = '';
 		await input.dispatchEvent(event);
 
-		assert.equal(component.count, undefined);
+		assert.equal(component.count, null);
 		assert.htmlEqual(target.innerHTML, `
 			<input type='number'>
-			<p>undefined undefined</p>
+			<p>object null</p>
 		`);
 	},
 };
Repository: sveltejs/svelte (JavaScript) — Bug Fix

Issue:
Build fails – TypeError: alt_value.match is not a function
Enter `<img alt>` in a REPL.

Cause: https://github.com/sveltejs/svelte/blob/master/src/compiler/compile/nodes/Element.ts#L491


Discussion:

Resolving patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,9 @@
 # Svelte changelog
 
+## Unreleased
+
+* Fix compiler exception with `a11y-img-redundant-alt` and value-less `alt` attribute ([#4777](https://github.com/sveltejs/svelte/issues/4777))
+
 ## 3.22.1
 
 * Fix compiler exception with `a11y-img-redundant-alt` and dynamic `alt` attribute ([#4770](https://github.com/sveltejs/svelte/issues/4770))
diff --git a/src/compiler/compile/nodes/Element.ts b/src/compiler/compile/nodes/Element.ts
--- a/src/compiler/compile/nodes/Element.ts
+++ b/src/compiler/compile/nodes/Element.ts
@@ -488,7 +488,7 @@ export default class Element extends Node {
 			if (alt_attribute && !aria_hidden_exist) {
 				const alt_value = alt_attribute.get_static_value();
 
-				if (alt_value && alt_value.match(/\b(image|picture|photo)\b/i)) {
+				if (/\b(image|picture|photo)\b/i.test(alt_value)) {
 					component.warn(this, {
 						code: `a11y-img-redundant-alt`,
 						message: `A11y: Screenreaders already announce <img> elements as an image.`


Test patch:
diff --git a/test/validator/samples/a11y-img-redundant-alt/input.svelte b/test/validator/samples/a11y-img-redundant-alt/input.svelte
--- a/test/validator/samples/a11y-img-redundant-alt/input.svelte
+++ b/test/validator/samples/a11y-img-redundant-alt/input.svelte
@@ -6,3 +6,4 @@
 <img src="bar" alt="Plant doing photosynthesis in the afternoon" />
 <img src="foo" alt="Picturesque food" />
 <img src="baz" alt={'baz'} />
+<img src="baz" alt />
Repository: sveltejs/svelte (JavaScript) — Bug Fix

Issue:
Spread props + bind:group + value
It's very weird behavior!

When I use `spread props`, the attribute `value` is not rendering.

I did a REPL:
https://svelte.dev/repl/73b2780bd1744b189564ffca010c2aec?version=3.22.2

Example (fragment in REPL):

```svelte
<input
  type="radio"
  id="{name}_{idx}"
  {value}
  {...props}
  bind:group={$store[name]}
/>
```
![image](https://user-images.githubusercontent.com/130963/81442266-aaa80680-9149-11ea-9e5e-2639e7493e74.png)

---

Workaround to work:

```svelte
<input
  type="radio"
  id="{name}_{idx}"
  {value}
  {...{...props, value}}
  bind:group={$store[name]}
/>
```

Spread props + bind:group + value
It's very weird behavior!

When I use `spread props`, the attribute `value` is not rendering.

I did a REPL:
https://svelte.dev/repl/73b2780bd1744b189564ffca010c2aec?version=3.22.2

Example (fragment in REPL):

```svelte
<input
  type="radio"
  id="{name}_{idx}"
  {value}
  {...props}
  bind:group={$store[name]}
/>
```
![image](https://user-images.githubusercontent.com/130963/81442266-aaa80680-9149-11ea-9e5e-2639e7493e74.png)

---

Workaround to work:

```svelte
<input
  type="radio"
  id="{name}_{idx}"
  {value}
  {...{...props, value}}
  bind:group={$store[name]}
/>
```



Discussion:

Resolving patch:
diff --git a/src/runtime/internal/dom.ts b/src/runtime/internal/dom.ts
--- a/src/runtime/internal/dom.ts
+++ b/src/runtime/internal/dom.ts
@@ -98,7 +98,9 @@ export function set_attributes(node: Element & ElementCSSInlineStyle, attributes
 			node.removeAttribute(key);
 		} else if (key === 'style') {
 			node.style.cssText = attributes[key];
-		} else if (key === '__value' || descriptors[key] && descriptors[key].set) {
+		} else if (key === '__value') {
+			(node as any).value = node[key] = attributes[key];
+		} else if (descriptors[key] && descriptors[key].set) {
 			node[key] = attributes[key];
 		} else {
 			attr(node, key, attributes[key]);


Test patch:
diff --git a/test/runtime/samples/spread-element-input-bind-group-with-value-attr/_config.js b/test/runtime/samples/spread-element-input-bind-group-with-value-attr/_config.js
new file mode 100644
--- /dev/null
+++ b/test/runtime/samples/spread-element-input-bind-group-with-value-attr/_config.js
@@ -0,0 +1,15 @@
+export default {
+	props: {
+		props: {
+			'data-foo': 'bar'
+		}
+	},
+
+	html: `<input data-foo="bar" type="radio" value="abc">`,
+
+	async test({ assert, component, target, window }) {
+		const input = target.querySelector('input');
+		assert.equal(input.value, 'abc');
+		assert.equal(input.__value, 'abc');
+	}
+};
diff --git a/test/runtime/samples/spread-element-input-bind-group-with-value-attr/main.svelte b/test/runtime/samples/spread-element-input-bind-group-with-value-attr/main.svelte
new file mode 100644
--- /dev/null
+++ b/test/runtime/samples/spread-element-input-bind-group-with-value-attr/main.svelte
@@ -0,0 +1,6 @@
+<script>
+	export let props;
+	let radioValue;
+</script>
+
+<input type="radio" value="abc" {...props} bind:group={radioValue} />
Repository: sveltejs/svelte (JavaScript) — Bug Fix

Issue:
Compiler crashes with orphaned :global in CSS
**Describe the bug**

CSS like this causes the Svelte compiler to crash:
```
<style>
  .codemirror-container.flex :global {padding:0}
</style>
```

**To Reproduce**
https://svelte.dev/repl/c0b2792175ab48c0afb84b01b9bfa247?version=3.23.0

**Expected behavior**
Throw an error instead of crashing.

**Severity**

Very minor since it's invalid syntax and nobody would intentionally write this. This happened because I had purgecss in my postcss preprocessor config and I needed to whitelist some classes.



Discussion:

Resolving patch:
diff --git a/src/compiler/parse/read/style.ts b/src/compiler/parse/read/style.ts
--- a/src/compiler/parse/read/style.ts
+++ b/src/compiler/parse/read/style.ts
@@ -54,6 +54,13 @@ export default function read_style(parser: Parser, start: number, attributes: No
 				}, node.start);
 			}
 
+			if (node.type === 'PseudoClassSelector' && node.name === 'global' && node.children === null) {
+				parser.error({
+					code: `css-syntax-error`,
+					message: `:global() must contain a selector`
+				}, node.loc.start.offset);
+			}
+
 			if (node.loc) {
 				node.start = node.loc.start.offset;
 				node.end = node.loc.end.offset;
@@ -87,4 +94,4 @@ function is_ref_selector(a: any, b: any) { // TODO add CSS node types
 		a.name === 'ref' &&
 		b.type === 'PseudoClassSelector'
 	);
-}
\ No newline at end of file
+}


Test patch:
diff --git a/test/parser/samples/error-css-global-without-selector/error.json b/test/parser/samples/error-css-global-without-selector/error.json
new file mode 100644
--- /dev/null
+++ b/test/parser/samples/error-css-global-without-selector/error.json
@@ -0,0 +1,10 @@
+{
+	"code": "css-syntax-error",
+	"message": ":global() must contain a selector",
+	"start": {
+		"line": 2,
+		"column": 1,
+		"character": 9
+	},
+	"pos": 9
+}
diff --git a/test/parser/samples/error-css-global-without-selector/input.svelte b/test/parser/samples/error-css-global-without-selector/input.svelte
new file mode 100644
--- /dev/null
+++ b/test/parser/samples/error-css-global-without-selector/input.svelte
@@ -0,0 +1,3 @@
+<style>
+	:global {}
+</style>
Repository: sveltejs/svelte (JavaScript) — Bug Fix

Issue:
Keyed each is not reactive to key expression dependencies
https://svelte.dev/repl/b1ed6b7fc7cf47ce9fc75f0555bcd799?version=3.26.0
```svelte
<script>
	export let id = 0;
</script>
{#each ["foo", "bar"] as key(id + key)}
	{Math.random()}
{/each}
```
Expected a different result on every `id` change


Discussion:

Resolving patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,7 @@
 
 ## Unreleased
 
+* Fix keyed `{#each}` not reacting to key changing ([#5444](https://github.com/sveltejs/svelte/issues/5444))
 * Fix destructuring into store values ([#5449](https://github.com/sveltejs/svelte/issues/5449))
 * Fix erroneous `missing-declaration` warning with `use:obj.method` ([#5451](https://github.com/sveltejs/svelte/issues/5451))
 
diff --git a/src/compiler/compile/render_dom/wrappers/EachBlock.ts b/src/compiler/compile/render_dom/wrappers/EachBlock.ts
--- a/src/compiler/compile/render_dom/wrappers/EachBlock.ts
+++ b/src/compiler/compile/render_dom/wrappers/EachBlock.ts
@@ -239,6 +239,11 @@ export default class EachBlockWrapper extends Wrapper {
 		this.node.expression.dynamic_dependencies().forEach((dependency: string) => {
 			all_dependencies.add(dependency);
 		});
+		if (this.node.key) {
+			this.node.key.dynamic_dependencies().forEach((dependency: string) => {
+				all_dependencies.add(dependency);
+			});
+		}
 		this.dependencies = all_dependencies;
 
 		if (this.node.key) {


Test patch:
diff --git a/test/runtime/samples/each-block-keyed-dyanmic-key/_config.js b/test/runtime/samples/each-block-keyed-dyanmic-key/_config.js
new file mode 100644
--- /dev/null
+++ b/test/runtime/samples/each-block-keyed-dyanmic-key/_config.js
@@ -0,0 +1,27 @@
+let count = 0;
+let value = 'foo';
+
+export default {
+	props: {
+		value() {
+			count++;
+			return value;
+		}
+	},
+
+	html: `
+		<div>foo</div>
+		<div>foo</div>
+	`,
+
+	test({ assert, component, target }) {
+		value = 'bar';
+		component.id = 1;
+
+		assert.equal(count, 4);
+		assert.htmlEqual(target.innerHTML, `
+			<div>bar</div>
+			<div>bar</div>
+		`);
+	}
+};
diff --git a/test/runtime/samples/each-block-keyed-dyanmic-key/main.svelte b/test/runtime/samples/each-block-keyed-dyanmic-key/main.svelte
new file mode 100644
--- /dev/null
+++ b/test/runtime/samples/each-block-keyed-dyanmic-key/main.svelte
@@ -0,0 +1,8 @@
+<script>
+	export let id = 0;
+	export let value;
+</script>
+
+{#each ['foo', 'bar'] as key (id + key)}
+	<div>{value()}</div>
+{/each}
\ No newline at end of file
Repository: sveltejs/svelte (JavaScript) — Bug Fix

Issue:
3.16.0 Support use:obj.method as actions returns a svelte(missing-decalaration)
Using support for 'use:obj.method={..}' returns:
- (!) Plugin svelte: 'test1.say' is not defined
- (!) Plugin svelte: 'test2.say' is not defined

```
<script>
  class Test {
    say(node, msg) {
      node.innerHTML = 'class: ' + msg;
    };
  }
  const test2 = new Test();

  const test1 = {
    say(node, msg) {
      node.innerHTML = 'obj: ' + msg;
    }
  };

  function test(node, msg) {
    node.innerHTML = msg;
  };
  let hi = 'Hi';
</script>

<div use:test={hi}></div>
<!-- svelte-ignore missing-declaration -->
<div use:test1.say={hi}></div>
<!-- svelte-ignore missing-declaration -->
<div use:test2.say={hi}></div> -->
```



Discussion:

Resolving patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,9 @@
 # Svelte changelog
 
+## Unreleased
+
+* Fix erroneous `missing-declaration` warning with `use:obj.method` ([#5451](https://github.com/sveltejs/svelte/issues/5451))
+
 ## 3.26.0
 
 * Support `use:obj.method` as actions ([#3935](https://github.com/sveltejs/svelte/issues/3935))
diff --git a/src/compiler/compile/nodes/Action.ts b/src/compiler/compile/nodes/Action.ts
--- a/src/compiler/compile/nodes/Action.ts
+++ b/src/compiler/compile/nodes/Action.ts
@@ -11,10 +11,11 @@ export default class Action extends Node {
 	constructor(component: Component, parent, scope, info) {
 		super(component, parent, scope, info);
 
-		component.warn_if_undefined(info.name, info, scope);
+		const object = info.name.split('.')[0];
+		component.warn_if_undefined(object, info, scope);
 
 		this.name = info.name;
-		component.add_reference(info.name.split('.')[0]);
+		component.add_reference(object);
 
 		this.expression = info.expression
 			? new Expression(component, this, scope, info.expression)


Test patch:
diff --git a/test/validator/samples/action-object/input.svelte b/test/validator/samples/action-object/input.svelte
new file mode 100644
--- /dev/null
+++ b/test/validator/samples/action-object/input.svelte
@@ -0,0 +1,11 @@
+<script>
+	const obj = {
+		foo : "bar",
+		action(element, { leet }) {
+			element.foo = this.foo + leet;
+		},
+	}
+</script>
+
+<button use:obj.action={{ leet: 1337 }}>action</button>
+<button use:foo.action={{ leet: 1337 }}>action</button>
\ No newline at end of file
diff --git a/test/validator/samples/action-object/warnings.json b/test/validator/samples/action-object/warnings.json
new file mode 100644
--- /dev/null
+++ b/test/validator/samples/action-object/warnings.json
@@ -0,0 +1,17 @@
+[
+	{
+		"code": "missing-declaration",
+		"end": {
+			"character": 217,
+			"column": 39,
+			"line": 11
+		},
+		"message": "'foo' is not defined",
+		"pos": 186,
+		"start": {
+			"character": 186,
+			"column": 8,
+			"line": 11
+		}
+	}
+]
Repository: sveltejs/svelte (JavaScript) — Bug Fix

Issue:
Order of html tags changes when using key > if
I need to display html when variable (in this repl - `num`) is truthy

And I also need to animate `first` tag after each change of another variable(`slide`)

If I have html structure like this:
```svelte
{#key animateOnChangeVariable}
  {#if variableIsTrythy}
    <div class="first">First tag</div>
  {/if}
{/key}
<div class="second">Second tag</div>
```
And if `num` is changed, `first` tag is inserted after `second` (html order is changed)

REPL
https://svelte.dev/repl/3ba09b8c428c4ee58c77ff477b5fa632?version=3.29.7



If `{#if}` and `{#key}` swapped, everything works correctly


Also, if you have several buttons at the same time, which change num by clicking - an error is thrown (uncomment second button, uncomment function and get error `div1 is not defined`).


Discussion:
I hope I described bug clearly

Resolving patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,7 @@
 
 ## Unreleased
 
+* Fix ordering of elements when using `{#if}` inside `{#key}` ([#5680](https://github.com/sveltejs/svelte/issues/5680))
 * Add `hasContext` lifecycle function ([#5690](https://github.com/sveltejs/svelte/pull/5690))
 * Fix missing `walk` types in `svelte/compiler` ([#5696](https://github.com/sveltejs/svelte/pull/5696))
 
diff --git a/src/compiler/compile/render_dom/wrappers/KeyBlock.ts b/src/compiler/compile/render_dom/wrappers/KeyBlock.ts
--- a/src/compiler/compile/render_dom/wrappers/KeyBlock.ts
+++ b/src/compiler/compile/render_dom/wrappers/KeyBlock.ts
@@ -44,7 +44,7 @@ export default class KeyBlockWrapper extends Wrapper {
 			renderer,
 			this.block,
 			node.children,
-			parent,
+			this,
 			strip_whitespace,
 			next_sibling
 		);


Test patch:
diff --git a/test/runtime/samples/key-block-static-if/_config.js b/test/runtime/samples/key-block-static-if/_config.js
new file mode 100644
--- /dev/null
+++ b/test/runtime/samples/key-block-static-if/_config.js
@@ -0,0 +1,21 @@
+export default {
+	html: `
+		<section>
+			<div>Second</div>
+		</section>
+		<button>Click</button>
+	`,
+	async test({ assert, component, target, window }) {
+		const button = target.querySelector('button');
+
+		await button.dispatchEvent(new window.Event('click'));
+
+		assert.htmlEqual(target.innerHTML, `
+			<section>
+				<div>First</div>
+				<div>Second</div>
+			</section>
+			<button>Click</button>
+		`);
+	}
+};
diff --git a/test/runtime/samples/key-block-static-if/main.svelte b/test/runtime/samples/key-block-static-if/main.svelte
new file mode 100644
--- /dev/null
+++ b/test/runtime/samples/key-block-static-if/main.svelte
@@ -0,0 +1,17 @@
+<script>
+	let slide = 0;
+	let num = false;
+	
+	const changeNum = () => num = !num;
+</script>
+
+<section>
+	{#key slide}
+		{#if num}
+			<div>First</div>
+		{/if}
+	{/key}
+	<div>Second</div>
+</section>
+
+<button on:click={changeNum}>Click</button>
\ No newline at end of file
Repository: sveltejs/svelte (JavaScript) — Bug Fix

Issue:
hasContext not exported
**Describe the bug**
`hasContext` is not exported from `src/runtime/index.ts`.

**Logs**
N/A

**To Reproduce**
Attempt to `import { hasContext } from 'svelte';`.

[REPL](https://svelte.dev/repl/6774f5ab24d146e19cb5fca6ac940389?version=3.30.0)

**Expected behavior**
I should be able to import the newly added `hasContext` lifecycle function.

**Stacktraces**
N/A

**Information about your Svelte project:**
N/A

**Severity**
Mild annoyance.

**Additional context**
This feature is brand new, so the export was likely just overlooked.



Discussion:

Resolving patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,9 @@
 # Svelte changelog
 
+## Unreleased
+
+* Actually export `hasContext` ([#5726](https://github.com/sveltejs/svelte/issues/5726))
+
 ## 3.30.0
 
 * Add a typed `SvelteComponent` interface ([#5431](https://github.com/sveltejs/svelte/pull/5431))
diff --git a/src/runtime/index.ts b/src/runtime/index.ts
--- a/src/runtime/index.ts
+++ b/src/runtime/index.ts
@@ -7,6 +7,7 @@ export {
 	afterUpdate,
 	setContext,
 	getContext,
+	hasContext,
 	tick,
 	createEventDispatcher,
 	SvelteComponentDev as SvelteComponent


Test patch:
diff --git a/test/runtime/samples/context-api-c/Leaf.svelte b/test/runtime/samples/context-api-c/Leaf.svelte
new file mode 100644
--- /dev/null
+++ b/test/runtime/samples/context-api-c/Leaf.svelte
@@ -0,0 +1,7 @@
+<script>
+	import { hasContext } from 'svelte';
+
+	const has = hasContext('test');
+</script>
+
+<div>{has}</div>
\ No newline at end of file
diff --git a/test/runtime/samples/context-api-c/Nested.svelte b/test/runtime/samples/context-api-c/Nested.svelte
new file mode 100644
--- /dev/null
+++ b/test/runtime/samples/context-api-c/Nested.svelte
@@ -0,0 +1,11 @@
+<script>
+	import { setContext } from 'svelte';
+
+	export let value = '';
+
+	if (value) {
+		setContext('test', value);
+	}
+</script>
+
+<slot></slot>
\ No newline at end of file
diff --git a/test/runtime/samples/context-api-c/_config.js b/test/runtime/samples/context-api-c/_config.js
new file mode 100644
--- /dev/null
+++ b/test/runtime/samples/context-api-c/_config.js
@@ -0,0 +1,6 @@
+export default {
+	html: `
+		<div>true</div>
+		<div>false</div>
+	`
+};
diff --git a/test/runtime/samples/context-api-c/main.svelte b/test/runtime/samples/context-api-c/main.svelte
new file mode 100644
--- /dev/null
+++ b/test/runtime/samples/context-api-c/main.svelte
@@ -0,0 +1,12 @@
+<script>
+  import Nested from "./Nested.svelte";
+  import Leaf from "./Leaf.svelte";
+</script>
+
+<Nested value="bar">
+  <Leaf />
+</Nested>
+
+<Nested>
+  <Leaf />
+</Nested>
Repository: sveltejs/svelte (JavaScript) — Feature

Issue:
Expect a compile error when class binding name is empty
**Is your feature request related to a problem? Please describe.**
Yes. Sometimes dev's maybe thought that this is a bug

**Describe the solution you'd like**
The compiler should give a compile error


**Additional context**
```svelte
<h1 class:={true}>Hello!</h1>
```
https://svelte.dev/repl/4afa49d00f544af18d89594881340a54?version=3.31.2


Discussion:

Resolving patch:
diff --git a/src/compiler/parse/state/tag.ts b/src/compiler/parse/state/tag.ts
--- a/src/compiler/parse/state/tag.ts
+++ b/src/compiler/parse/state/tag.ts
@@ -387,6 +387,13 @@ function read_attribute(parser: Parser, unique_names: Set<string>) {
 			}, start);
 		}
 
+		if (type === 'Class' && directive_name === '') {
+			parser.error({
+				code: 'invalid-class-directive',
+				message: 'Class binding name cannot be empty'
+			}, start + colon_index + 1);
+		}
+
 		if (value[0]) {
 			if ((value as any[]).length > 1 || value[0].type === 'Text') {
 				parser.error({


Test patch:
diff --git a/test/parser/samples/error-empty-classname-binding/error.json b/test/parser/samples/error-empty-classname-binding/error.json
new file mode 100644
--- /dev/null
+++ b/test/parser/samples/error-empty-classname-binding/error.json
@@ -0,0 +1,10 @@
+{
+	"code": "invalid-class-directive",
+	"message": "Class binding name cannot be empty",
+	"start": {
+		"line": 1,
+		"column": 10,
+		"character": 10
+	},
+	"pos": 10
+}
diff --git a/test/parser/samples/error-empty-classname-binding/input.svelte b/test/parser/samples/error-empty-classname-binding/input.svelte
new file mode 100644
--- /dev/null
+++ b/test/parser/samples/error-empty-classname-binding/input.svelte
@@ -0,0 +1 @@
+<h1 class:={true}>Hello</h1>
Repository: sveltejs/svelte (JavaScript) — Bug Fix

Issue:
Since 3.32.2 a single :host style selector is removed when producing web components
Is there a reason why, but the `:host` style selector is removed when compiling this. Works in svelte 3.32.1, but not in 3.32.2.

```
<style>
    :host {
        display: inline-block;
    }
    .hello {
        color: green
    }
</style>
```
*Result:*
only the .hello class is available in the compiled web component.


Discussion:

Resolving patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,9 @@
 # Svelte changelog
 
+## Unreleased
+
+* Fix removal of lone `:host` selectors ([#5982](https://github.com/sveltejs/svelte/issues/5982))
+
 ## 3.32.2
 
 * Fix unnecessary additional invalidation with `<Component bind:prop={obj.foo}/>` ([#3075](https://github.com/sveltejs/svelte/issues/3075), [#4447](https://github.com/sveltejs/svelte/issues/4447), [#5555](https://github.com/sveltejs/svelte/issues/5555))
diff --git a/src/compiler/compile/css/Selector.ts b/src/compiler/compile/css/Selector.ts
--- a/src/compiler/compile/css/Selector.ts
+++ b/src/compiler/compile/css/Selector.ts
@@ -44,7 +44,10 @@ export default class Selector {
 		}
 
 		this.local_blocks = this.blocks.slice(0, i);
-		this.used = this.local_blocks.length === 0;
+
+		const host_only = this.blocks.length === 1 && this.blocks[0].host;
+
+		this.used = this.local_blocks.length === 0 || host_only;
 	}
 
 	apply(node: Element) {


Test patch:
diff --git a/test/css/samples/host/expected.css b/test/css/samples/host/expected.css
--- a/test/css/samples/host/expected.css
+++ b/test/css/samples/host/expected.css
@@ -1 +1 @@
-:host h1.svelte-xyz{color:red}:host>h1.svelte-xyz{color:red}:host>.svelte-xyz{color:red}:host span.svelte-xyz{color:red}
\ No newline at end of file
+:host h1.svelte-xyz{color:red}:host>h1.svelte-xyz{color:red}:host>.svelte-xyz{color:red}:host span.svelte-xyz{color:red}:host{color:red}
\ No newline at end of file
diff --git a/test/css/samples/host/input.svelte b/test/css/samples/host/input.svelte
--- a/test/css/samples/host/input.svelte
+++ b/test/css/samples/host/input.svelte
@@ -18,6 +18,10 @@
 	:host > span {
 		color: red;
 	}
+
+  :host {
+    color: red;
+  }
 </style>
 
 <h1>Hello!</h1>
Repository: sveltejs/svelte (JavaScript) — Bug Fix

Issue:
Invalid "A11y: '#' is not a valid href attribute"
`<a href="#{'a'}">hello</a>`

The url is #a, not #.


Discussion:
```html
<script>
	let name = 'world';
</script>


<a href="#{name}">hello</a>
```

this seems to work 👀 

Resolving patch:
diff --git a/src/compiler/compile/nodes/Attribute.ts b/src/compiler/compile/nodes/Attribute.ts
--- a/src/compiler/compile/nodes/Attribute.ts
+++ b/src/compiler/compile/nodes/Attribute.ts
@@ -96,7 +96,7 @@ export default class Attribute extends Node {
 	}
 
 	get_static_value() {
-		if (this.is_spread || this.dependencies.size > 0) return null;
+		if (!this.is_static) return null;
 
 		return this.is_true
 			? true


Test patch:
diff --git a/test/validator/samples/a11y-anchor-has-content/input.svelte b/test/validator/samples/a11y-anchor-has-content/input.svelte
--- a/test/validator/samples/a11y-anchor-has-content/input.svelte
+++ b/test/validator/samples/a11y-anchor-has-content/input.svelte
@@ -1 +1,2 @@
-<a href='/foo'></a>
\ No newline at end of file
+<a href='/foo'></a>
+<a href="#{'foo'}">bar</a>
Repository: sveltejs/svelte (JavaScript) — Bug Fix

Issue:
No compile errors when passing empty directive names
Looks like I can pass empty directive names which can generate invalid JS code without any compilation errors or with unclear errors

For example in actions
```svelte
<element use: />
````
Parts of generated code looks like:
```javascript
dispose = action_destroyer(_action = .call(null, h1));
```

Same happens with event directive. but it does not throw JS syntax error
```javascript
dispose = listen(h1, "", /*_handler*/ ctx[0]);
```

With bind and animation directives. It throws an error because it is not able to look for the empty variable name in the component.

`[!] (plugin svelte) ValidationError:  is not declared`




Discussion:

Resolving patch:
diff --git a/src/compiler/parse/state/tag.ts b/src/compiler/parse/state/tag.ts
--- a/src/compiler/parse/state/tag.ts
+++ b/src/compiler/parse/state/tag.ts
@@ -378,6 +378,13 @@ function read_attribute(parser: Parser, unique_names: Set<string>) {
 	if (type) {
 		const [directive_name, ...modifiers] = name.slice(colon_index + 1).split('|');
 
+		if (directive_name === '') {
+			parser.error({
+				code: 'empty-directive-name',
+				message: `${type} name cannot be empty`
+			}, start + colon_index + 1);
+		}
+
 		if (type === 'Binding' && directive_name !== 'this') {
 			check_unique(directive_name);
 		} else if (type !== 'EventHandler' && type !== 'Action') {
@@ -391,13 +398,6 @@ function read_attribute(parser: Parser, unique_names: Set<string>) {
 			}, start);
 		}
 
-		if (type === 'Class' && directive_name === '') {
-			parser.error({
-				code: 'invalid-class-directive',
-				message: 'Class binding name cannot be empty'
-			}, start + colon_index + 1);
-		}
-
 		if (value[0]) {
 			if ((value as any[]).length > 1 || value[0].type === 'Text') {
 				parser.error({


Test patch:
diff --git a/test/parser/samples/error-empty-classname-binding/error.json b/test/parser/samples/error-empty-classname-binding/error.json
--- a/test/parser/samples/error-empty-classname-binding/error.json
+++ b/test/parser/samples/error-empty-classname-binding/error.json
@@ -1,6 +1,6 @@
 {
-	"code": "invalid-class-directive",
-	"message": "Class binding name cannot be empty",
+	"code": "empty-directive-name",
+	"message": "Class name cannot be empty",
 	"start": {
 		"line": 1,
 		"column": 10,
diff --git a/test/parser/samples/error-empty-directive-name/error.json b/test/parser/samples/error-empty-directive-name/error.json
new file mode 100644
--- /dev/null
+++ b/test/parser/samples/error-empty-directive-name/error.json
@@ -0,0 +1,10 @@
+{
+	"code": "empty-directive-name",
+	"message": "Action name cannot be empty",
+	"start": {
+		"line": 1,
+		"column": 8,
+		"character": 8
+	},
+	"pos": 8
+}
diff --git a/test/parser/samples/error-empty-directive-name/input.svelte b/test/parser/samples/error-empty-directive-name/input.svelte
new file mode 100644
--- /dev/null
+++ b/test/parser/samples/error-empty-directive-name/input.svelte
@@ -0,0 +1 @@
+<h1 use:>Hello</h1>
Repository: sveltejs/svelte (JavaScript) — Bug Fix

Issue:
:global applied to multiple selectors should be an error
**Describe the bug**
Prefixing a css global to give it scope only scopes the first selector.

**To Reproduce**
https://svelte.dev/repl/aaed36026d014e34b45aedef9630b55f?version=3.31.2

**Expected behavior**
```css
article.svelte-1nz7a1b div.svelte-1nz7a1b h1, article.svelte-1nz7a1b div.svelte-1nz7a1b h2, article.svelte-1nz7a1b div.svelte-1nz7a1b h3 {
    background-color: red;
}
```
**Current behaviour**
```css
article.svelte-1nz7a1b div.svelte-1nz7a1b h1, h2, h3 {
    background-color: red;
}
```

**Information about your Svelte project:**
Latest svelte repl.

**Severity**
Not severe.



Discussion:
Honestly I'm thinking that `:global(h1, h2, h3)` should probably be a compiler error. It's not really clear to me what it should mean. I don't think `article div :global(h1, h2, h3)` should be a shortcut for `article div :global(h1), article div :global(h2), article div :global(h3)`, which is what this issue seems to be suggesting.
It would be nice in the aspect of reducing redundant code, however keeping true to the native css way it would probably be best to not introduce some custom logic. But with that said, if `:global(h1, h2, h3)` would still continue to be acceptable I would regard this as unexpected behavior.

Resolving patch:
diff --git a/src/compiler/compile/css/Selector.ts b/src/compiler/compile/css/Selector.ts
--- a/src/compiler/compile/css/Selector.ts
+++ b/src/compiler/compile/css/Selector.ts
@@ -143,6 +143,19 @@ export default class Selector {
 				});
 			}
 		}
+
+		for (const block of this.blocks) {
+			for (const selector of block.selectors) {
+				if (selector.type === 'PseudoClassSelector' && selector.name === 'global') {
+					if (/[^\\],/.test(selector.children[0].value)) {
+						component.error(selector, {
+							code: 'css-invalid-global-selector',
+							message: ':global(...) must contain a single selector'
+						});
+					}
+				}
+			}
+		}
 	}
 
 	get_amount_class_specificity_increased() {


Test patch:
diff --git a/test/validator/samples/css-invalid-global-selector/errors.json b/test/validator/samples/css-invalid-global-selector/errors.json
new file mode 100644
--- /dev/null
+++ b/test/validator/samples/css-invalid-global-selector/errors.json
@@ -0,0 +1,17 @@
+[
+	{
+		"code": "css-invalid-global-selector",
+		"message": ":global(...) must contain a single selector",
+		"start": {
+			"line": 5,
+			"column": 5,
+			"character": 58
+		},
+		"end": {
+			"line": 5,
+			"column": 24,
+			"character": 77
+		},
+		"pos": 58
+	}
+]
diff --git a/test/validator/samples/css-invalid-global-selector/input.svelte b/test/validator/samples/css-invalid-global-selector/input.svelte
new file mode 100644
--- /dev/null
+++ b/test/validator/samples/css-invalid-global-selector/input.svelte
@@ -0,0 +1,12 @@
+<style>
+	div :global(.h1\,h2\,h3) {
+		color: red;
+	}
+	div :global(h1, h2, h3) {
+		color: red;
+	}
+</style>
+
+<div>
+	<h1>hello world</h1>
+</div>
\ No newline at end of file