@@ -872,11 +872,31 @@ function inferBlock(
872
872
reason : new Set ( [ ValueReason . Other ] ) ,
873
873
context : new Set ( ) ,
874
874
} ;
875
+
876
+ for ( const element of instrValue . elements ) {
877
+ if ( element . kind === 'Spread' ) {
878
+ state . referenceAndRecordEffects (
879
+ freezeActions ,
880
+ element . place ,
881
+ Effect . ConditionallyMutate ,
882
+ ValueReason . Other ,
883
+ ) ;
884
+ } else if ( element . kind === 'Identifier' ) {
885
+ state . referenceAndRecordEffects (
886
+ freezeActions ,
887
+ element ,
888
+ Effect . Capture ,
889
+ ValueReason . Other ,
890
+ ) ;
891
+ } else {
892
+ let _ : 'Hole' = element . kind ;
893
+ }
894
+ }
895
+ state . initialize ( instrValue , valueKind ) ;
896
+ state . define ( instr . lvalue , instrValue ) ;
897
+ instr . lvalue . effect = Effect . Store ;
875
898
continuation = {
876
- kind : 'initialize' ,
877
- valueKind,
878
- effect : { kind : Effect . Capture , reason : ValueReason . Other } ,
879
- lvalueEffect : Effect . Store ,
899
+ kind : 'funeffects' ,
880
900
} ;
881
901
break ;
882
902
}
@@ -1241,21 +1261,12 @@ function inferBlock(
1241
1261
for ( let i = 0 ; i < instrValue . args . length ; i ++ ) {
1242
1262
const arg = instrValue . args [ i ] ;
1243
1263
const place = arg . kind === 'Identifier' ? arg : arg . place ;
1244
- if ( effects !== null ) {
1245
- state . referenceAndRecordEffects (
1246
- freezeActions ,
1247
- place ,
1248
- effects [ i ] ,
1249
- ValueReason . Other ,
1250
- ) ;
1251
- } else {
1252
- state . referenceAndRecordEffects (
1253
- freezeActions ,
1254
- place ,
1255
- Effect . ConditionallyMutate ,
1256
- ValueReason . Other ,
1257
- ) ;
1258
- }
1264
+ state . referenceAndRecordEffects (
1265
+ freezeActions ,
1266
+ place ,
1267
+ getArgumentEffect ( effects != null ? effects [ i ] : null , arg ) ,
1268
+ ValueReason . Other ,
1269
+ ) ;
1259
1270
hasCaptureArgument ||= place . effect === Effect . Capture ;
1260
1271
}
1261
1272
if ( signature !== null ) {
@@ -1307,7 +1318,10 @@ function inferBlock(
1307
1318
signature !== null
1308
1319
? {
1309
1320
kind : signature . returnValueKind ,
1310
- reason : new Set ( [ ValueReason . Other ] ) ,
1321
+ reason : new Set ( [
1322
+ signature . returnValueReason ??
1323
+ ValueReason . KnownReturnSignature ,
1324
+ ] ) ,
1311
1325
context : new Set ( ) ,
1312
1326
}
1313
1327
: {
@@ -1330,7 +1344,8 @@ function inferBlock(
1330
1344
state . referenceAndRecordEffects (
1331
1345
freezeActions ,
1332
1346
place ,
1333
- Effect . Read ,
1347
+ // see call-spread-argument-mutable-iterator test fixture
1348
+ arg . kind === 'Spread' ? Effect . ConditionallyMutate : Effect . Read ,
1334
1349
ValueReason . Other ,
1335
1350
) ;
1336
1351
}
@@ -1356,25 +1371,16 @@ function inferBlock(
1356
1371
for ( let i = 0 ; i < instrValue . args . length ; i ++ ) {
1357
1372
const arg = instrValue . args [ i ] ;
1358
1373
const place = arg . kind === 'Identifier' ? arg : arg . place ;
1359
- if ( effects !== null ) {
1360
- /*
1361
- * If effects are inferred for an argument, we should fail invalid
1362
- * mutating effects
1363
- */
1364
- state . referenceAndRecordEffects (
1365
- freezeActions ,
1366
- place ,
1367
- effects [ i ] ,
1368
- ValueReason . Other ,
1369
- ) ;
1370
- } else {
1371
- state . referenceAndRecordEffects (
1372
- freezeActions ,
1373
- place ,
1374
- Effect . ConditionallyMutate ,
1375
- ValueReason . Other ,
1376
- ) ;
1377
- }
1374
+ /*
1375
+ * If effects are inferred for an argument, we should fail invalid
1376
+ * mutating effects
1377
+ */
1378
+ state . referenceAndRecordEffects (
1379
+ freezeActions ,
1380
+ place ,
1381
+ getArgumentEffect ( effects != null ? effects [ i ] : null , arg ) ,
1382
+ ValueReason . Other ,
1383
+ ) ;
1378
1384
hasCaptureArgument ||= place . effect === Effect . Capture ;
1379
1385
}
1380
1386
if ( signature !== null ) {
@@ -2049,3 +2055,31 @@ function areArgumentsImmutableAndNonMutating(
2049
2055
}
2050
2056
return true ;
2051
2057
}
2058
+
2059
+ function getArgumentEffect (
2060
+ signatureEffect : Effect | null ,
2061
+ arg : Place | SpreadPattern ,
2062
+ ) : Effect {
2063
+ if ( signatureEffect != null ) {
2064
+ if ( arg . kind === 'Identifier' ) {
2065
+ return signatureEffect ;
2066
+ } else if (
2067
+ signatureEffect === Effect . Mutate ||
2068
+ signatureEffect === Effect . ConditionallyMutate
2069
+ ) {
2070
+ return signatureEffect ;
2071
+ } else {
2072
+ // see call-spread-argument-mutable-iterator test fixture
2073
+ if ( signatureEffect === Effect . Freeze ) {
2074
+ CompilerError . throwTodo ( {
2075
+ reason : 'Support spread syntax for hook arguments' ,
2076
+ loc : arg . place . loc ,
2077
+ } ) ;
2078
+ }
2079
+ // effects[i] is Effect.Capture | Effect.Read | Effect.Store
2080
+ return Effect . ConditionallyMutate ;
2081
+ }
2082
+ } else {
2083
+ return Effect . ConditionallyMutate ;
2084
+ }
2085
+ }
0 commit comments