Skip to content

Commit 24777c3

Browse files
authored
feat: disallow fallback values with bindings in runes mode (#9784)
* disallow fallback values with bindings in runes mode * on second thoughts --------- Co-authored-by: Rich Harris <[email protected]>
1 parent c7e626e commit 24777c3

File tree

9 files changed

+52
-112
lines changed

9 files changed

+52
-112
lines changed

.changeset/polite-ravens-study.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'svelte': patch
3+
---
4+
5+
feat: disallow fallback values with bindings in runes mode

packages/svelte/src/compiler/phases/3-transform/client/utils.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
import * as b from '../../../utils/builders.js';
22
import { extract_paths, is_simple_expression } from '../../../utils/ast.js';
33
import { error } from '../../../errors.js';
4-
import { PROPS_CALL_DEFAULT_VALUE, PROPS_IS_IMMUTABLE } from '../../../../constants.js';
4+
import {
5+
PROPS_CALL_DEFAULT_VALUE,
6+
PROPS_IS_IMMUTABLE,
7+
PROPS_IS_RUNES
8+
} from '../../../../constants.js';
59

610
/**
711
* @template {import('./types').ClientTransformState} State
@@ -369,6 +373,10 @@ export function get_props_method(binding, state, name, default_value) {
369373
flags |= PROPS_IS_IMMUTABLE;
370374
}
371375

376+
if (state.analysis.runes) {
377+
flags |= PROPS_IS_RUNES;
378+
}
379+
372380
if (default_value) {
373381
// To avoid eagerly evaluating the right-hand-side, we wrap it in a thunk if necessary
374382
if (is_simple_expression(default_value)) {

packages/svelte/src/constants.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ export const EACH_IS_ANIMATED = 1 << 4;
66
export const EACH_IS_IMMUTABLE = 1 << 6;
77

88
export const PROPS_IS_IMMUTABLE = 1;
9-
export const PROPS_CALL_DEFAULT_VALUE = 1 << 1;
9+
export const PROPS_IS_RUNES = 1 << 1;
10+
export const PROPS_CALL_DEFAULT_VALUE = 1 << 2;
1011

1112
/** List of Element events that will be delegated */
1213
export const DelegatedEvents = [

packages/svelte/src/internal/client/runtime.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { DEV } from 'esm-env';
22
import { subscribe_to_store } from '../../store/utils.js';
33
import { EMPTY_FUNC, run_all } from '../common.js';
44
import { get_descriptor, get_descriptors, is_array } from './utils.js';
5-
import { PROPS_CALL_DEFAULT_VALUE, PROPS_IS_IMMUTABLE } from '../../constants.js';
5+
import { PROPS_CALL_DEFAULT_VALUE, PROPS_IS_IMMUTABLE, PROPS_IS_RUNES } from '../../constants.js';
66

77
export const SOURCE = 1;
88
export const DERIVED = 1 << 1;
@@ -1428,6 +1428,11 @@ export function prop_source(props_obj, key, flags, default_value) {
14281428
let value = props[key];
14291429
const should_set_default_value = value === undefined && default_value !== undefined;
14301430

1431+
if (update_bound_prop && default_value !== undefined && (flags & PROPS_IS_RUNES) !== 0) {
1432+
// TODO consolidate all these random runtime errors
1433+
throw new Error('Cannot use fallback values with bind:');
1434+
}
1435+
14311436
if (should_set_default_value) {
14321437
value =
14331438
// @ts-expect-error would need a cumbersome method overload to type this

packages/svelte/tests/runtime-runes/samples/props-bound-fallback/_config.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,7 @@ export default test({
1212
await btn?.click();
1313

1414
assert.htmlEqual(target.innerHTML, `<button>1</button><span>1</span>`);
15-
}
15+
},
16+
17+
error: `Cannot use fallback values with bind:`
1618
});

packages/svelte/tests/runtime-runes/samples/props-default-value-behavior/_config.js

Lines changed: 23 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ export default test({
1010
readonly:
1111
readonlyWithDefault: 1
1212
binding:
13-
bindingWithDefault: 1
1413
</p>
1514
<button>set bindings to 5</button>
1615
<button>set bindings to undefined</button>
@@ -20,27 +19,24 @@ export default test({
2019
readonly: 0
2120
readonlyWithDefault: 0
2221
binding: 0
23-
bindingWithDefault: 0
2422
</p>
2523
<button>set bindings to 5</button>
2624
<button>set bindings to undefined</button>
27-
25+
2826
<p>bindings undefined:</p>
2927
<p>
3028
readonly:
3129
readonlyWithDefault: 1
3230
binding:
33-
bindingWithDefault: 1
3431
</p>
3532
<button>set bindings to 5</button>
3633
<button>set bindings to undefined</button>
37-
34+
3835
<p>bindings defined:</p>
3936
<p>
4037
readonly: 0
4138
readonlyWithDefault: 0
4239
binding: 0
43-
bindingWithDefault: 0
4440
</p>
4541
<button>set bindings to 5</button>
4642
<button>set bindings to undefined</button>
@@ -50,19 +46,13 @@ export default test({
5046
readonly_undefined:
5147
readonlyWithDefault_undefined:
5248
binding_undefined:
53-
bindingWithDefault_undefined:
5449
readonly_defined: 0
5550
readonlyWithDefault_defined: 0
5651
binding_defined: 0
57-
bindingWithDefault_defined: 0
5852
bind_readonly_undefined:
59-
bind_readonlyWithDefault_undefined: 1
6053
bind_binding_undefined:
61-
bind_bindingWithDefault_undefined: 1
6254
bind_readonly_defined: 0
63-
bind_readonlyWithDefault_defined: 0
6455
bind_binding_defined: 0
65-
bind_bindingWithDefault_defined: 0
6656
</p>
6757
6858
<button>set everything to 10</button>
@@ -93,64 +83,54 @@ export default test({
9383
`
9484
<p>props undefined:</p>
9585
<p>
96-
readonly:
86+
readonly:
9787
readonlyWithDefault: 1
9888
binding:
99-
bindingWithDefault:
10089
</p>
10190
<button>set bindings to 5</button>
10291
<button>set bindings to undefined</button>
103-
92+
10493
<p>props defined:</p>
10594
<p>
10695
readonly: 0
10796
readonlyWithDefault: 0
10897
binding:
109-
bindingWithDefault:
11098
</p>
11199
<button>set bindings to 5</button>
112100
<button>set bindings to undefined</button>
113-
101+
114102
<p>bindings undefined:</p>
115103
<p>
116104
readonly:
117105
readonlyWithDefault: 1
118106
binding:
119-
bindingWithDefault:
120107
</p>
121108
<button>set bindings to 5</button>
122109
<button>set bindings to undefined</button>
123-
110+
124111
<p>bindings defined:</p>
125112
<p>
126113
readonly: 0
127114
readonlyWithDefault: 0
128115
binding:
129-
bindingWithDefault:
130116
</p>
131117
<button>set bindings to 5</button>
132118
<button>set bindings to undefined</button>
133-
119+
134120
<p>
135121
Main:
136122
readonly_undefined:
137123
readonlyWithDefault_undefined:
138124
binding_undefined:
139-
bindingWithDefault_undefined:
140125
readonly_defined: 0
141126
readonlyWithDefault_defined: 0
142127
binding_defined: 0
143-
bindingWithDefault_defined: 0
144128
bind_readonly_undefined:
145-
bind_readonlyWithDefault_undefined: 1
146129
bind_binding_undefined:
147-
bind_bindingWithDefault_undefined:
148130
bind_readonly_defined: 0
149-
bind_readonlyWithDefault_defined: 0
150131
bind_binding_defined:
151-
bind_bindingWithDefault_defined:
152132
</p>
153-
133+
154134
<button>set everything to 10</button>
155135
<button>set everything to undefined</button>
156136
`
@@ -169,61 +149,51 @@ export default test({
169149
readonly:
170150
readonlyWithDefault: 1
171151
binding: 5
172-
bindingWithDefault: 5
173152
</p>
174153
<button>set bindings to 5</button>
175154
<button>set bindings to undefined</button>
176-
155+
177156
<p>props defined:</p>
178157
<p>
179158
readonly: 0
180159
readonlyWithDefault: 0
181160
binding: 5
182-
bindingWithDefault: 5
183161
</p>
184162
<button>set bindings to 5</button>
185163
<button>set bindings to undefined</button>
186-
164+
187165
<p>bindings undefined:</p>
188166
<p>
189167
readonly:
190168
readonlyWithDefault: 1
191169
binding: 5
192-
bindingWithDefault: 5
193170
</p>
194171
<button>set bindings to 5</button>
195172
<button>set bindings to undefined</button>
196-
173+
197174
<p>bindings defined:</p>
198175
<p>
199176
readonly: 0
200177
readonlyWithDefault: 0
201178
binding: 5
202-
bindingWithDefault: 5
203179
</p>
204180
<button>set bindings to 5</button>
205181
<button>set bindings to undefined</button>
206-
182+
207183
<p>
208184
Main:
209185
readonly_undefined:
210186
readonlyWithDefault_undefined:
211187
binding_undefined:
212-
bindingWithDefault_undefined:
213188
readonly_defined: 0
214189
readonlyWithDefault_defined: 0
215190
binding_defined: 0
216-
bindingWithDefault_defined: 0
217191
bind_readonly_undefined:
218-
bind_readonlyWithDefault_undefined: 1
219192
bind_binding_undefined: 5
220-
bind_bindingWithDefault_undefined: 5
221193
bind_readonly_defined: 0
222-
bind_readonlyWithDefault_defined: 0
223194
bind_binding_defined: 5
224-
bind_bindingWithDefault_defined: 5
225195
</p>
226-
196+
227197
<button>set everything to 10</button>
228198
<button>set everything to undefined</button>
229199
`
@@ -239,61 +209,51 @@ export default test({
239209
readonly: 10
240210
readonlyWithDefault: 10
241211
binding: 10
242-
bindingWithDefault: 10
243212
</p>
244213
<button>set bindings to 5</button>
245214
<button>set bindings to undefined</button>
246-
215+
247216
<p>props defined:</p>
248217
<p>
249218
readonly: 10
250219
readonlyWithDefault: 10
251220
binding: 10
252-
bindingWithDefault: 10
253221
</p>
254222
<button>set bindings to 5</button>
255223
<button>set bindings to undefined</button>
256-
224+
257225
<p>bindings undefined:</p>
258226
<p>
259227
readonly: 10
260228
readonlyWithDefault: 10
261229
binding: 10
262-
bindingWithDefault: 10
263230
</p>
264231
<button>set bindings to 5</button>
265232
<button>set bindings to undefined</button>
266-
233+
267234
<p>bindings defined:</p>
268235
<p>
269236
readonly: 10
270237
readonlyWithDefault: 10
271238
binding: 10
272-
bindingWithDefault: 10
273239
</p>
274240
<button>set bindings to 5</button>
275241
<button>set bindings to undefined</button>
276-
242+
277243
<p>
278244
Main:
279245
readonly_undefined: 10
280246
readonlyWithDefault_undefined: 10
281247
binding_undefined: 10
282-
bindingWithDefault_undefined: 10
283248
readonly_defined: 10
284249
readonlyWithDefault_defined: 10
285250
binding_defined: 10
286-
bindingWithDefault_defined: 10
287251
bind_readonly_undefined: 10
288-
bind_readonlyWithDefault_undefined: 10
289252
bind_binding_undefined: 10
290-
bind_bindingWithDefault_undefined: 10
291253
bind_readonly_defined: 10
292-
bind_readonlyWithDefault_defined: 10
293254
bind_binding_defined: 10
294-
bind_bindingWithDefault_defined: 10
295255
</p>
296-
256+
297257
<button>set everything to 10</button>
298258
<button>set everything to undefined</button>
299259
`
@@ -309,61 +269,51 @@ export default test({
309269
readonly:
310270
readonlyWithDefault:
311271
binding:
312-
bindingWithDefault:
313272
</p>
314273
<button>set bindings to 5</button>
315274
<button>set bindings to undefined</button>
316-
275+
317276
<p>props defined:</p>
318277
<p>
319278
readonly:
320279
readonlyWithDefault:
321280
binding:
322-
bindingWithDefault:
323281
</p>
324282
<button>set bindings to 5</button>
325283
<button>set bindings to undefined</button>
326-
284+
327285
<p>bindings undefined:</p>
328286
<p>
329287
readonly:
330288
readonlyWithDefault:
331289
binding:
332-
bindingWithDefault:
333290
</p>
334291
<button>set bindings to 5</button>
335292
<button>set bindings to undefined</button>
336-
293+
337294
<p>bindings defined:</p>
338295
<p>
339296
readonly:
340297
readonlyWithDefault:
341298
binding:
342-
bindingWithDefault:
343299
</p>
344300
<button>set bindings to 5</button>
345301
<button>set bindings to undefined</button>
346-
302+
347303
<p>
348304
Main:
349305
readonly_undefined:
350306
readonlyWithDefault_undefined:
351307
binding_undefined:
352-
bindingWithDefault_undefined:
353308
readonly_defined:
354309
readonlyWithDefault_defined:
355310
binding_defined:
356-
bindingWithDefault_defined:
357311
bind_readonly_undefined:
358-
bind_readonlyWithDefault_undefined:
359312
bind_binding_undefined:
360-
bind_bindingWithDefault_undefined:
361313
bind_readonly_defined:
362-
bind_readonlyWithDefault_defined:
363314
bind_binding_defined:
364-
bind_bindingWithDefault_defined:
365315
</p>
366-
316+
367317
<button>set everything to 10</button>
368318
<button>set everything to undefined</button>
369319
`

0 commit comments

Comments
 (0)