@@ -872,11 +872,33 @@ 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
+ isArrayType ( element . place . identifier )
882
+ ? Effect . Capture
883
+ : Effect . ConditionallyMutate ,
884
+ ValueReason . Other ,
885
+ ) ;
886
+ } else if ( element . kind === 'Identifier' ) {
887
+ state . referenceAndRecordEffects (
888
+ freezeActions ,
889
+ element ,
890
+ Effect . Capture ,
891
+ ValueReason . Other ,
892
+ ) ;
893
+ } else {
894
+ let _ : 'Hole' = element . kind ;
895
+ }
896
+ }
897
+ state . initialize ( instrValue , valueKind ) ;
898
+ state . define ( instr . lvalue , instrValue ) ;
899
+ instr . lvalue . effect = Effect . Store ;
875
900
continuation = {
876
- kind : 'initialize' ,
877
- valueKind,
878
- effect : { kind : Effect . Capture , reason : ValueReason . Other } ,
879
- lvalueEffect : Effect . Store ,
901
+ kind : 'funeffects' ,
880
902
} ;
881
903
break ;
882
904
}
@@ -1241,21 +1263,12 @@ function inferBlock(
1241
1263
for ( let i = 0 ; i < instrValue . args . length ; i ++ ) {
1242
1264
const arg = instrValue . args [ i ] ;
1243
1265
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
- }
1266
+ state . referenceAndRecordEffects (
1267
+ freezeActions ,
1268
+ place ,
1269
+ getArgumentEffect ( effects != null ? effects [ i ] : null , arg ) ,
1270
+ ValueReason . Other ,
1271
+ ) ;
1259
1272
hasCaptureArgument ||= place . effect === Effect . Capture ;
1260
1273
}
1261
1274
if ( signature !== null ) {
@@ -1307,7 +1320,10 @@ function inferBlock(
1307
1320
signature !== null
1308
1321
? {
1309
1322
kind : signature . returnValueKind ,
1310
- reason : new Set ( [ ValueReason . Other ] ) ,
1323
+ reason : new Set ( [
1324
+ signature . returnValueReason ??
1325
+ ValueReason . KnownReturnSignature ,
1326
+ ] ) ,
1311
1327
context : new Set ( ) ,
1312
1328
}
1313
1329
: {
@@ -1356,25 +1372,16 @@ function inferBlock(
1356
1372
for ( let i = 0 ; i < instrValue . args . length ; i ++ ) {
1357
1373
const arg = instrValue . args [ i ] ;
1358
1374
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
- }
1375
+ /*
1376
+ * If effects are inferred for an argument, we should fail invalid
1377
+ * mutating effects
1378
+ */
1379
+ state . referenceAndRecordEffects (
1380
+ freezeActions ,
1381
+ place ,
1382
+ getArgumentEffect ( effects != null ? effects [ i ] : null , arg ) ,
1383
+ ValueReason . Other ,
1384
+ ) ;
1378
1385
hasCaptureArgument ||= place . effect === Effect . Capture ;
1379
1386
}
1380
1387
if ( signature !== null ) {
@@ -2049,3 +2056,31 @@ function areArgumentsImmutableAndNonMutating(
2049
2056
}
2050
2057
return true ;
2051
2058
}
2059
+
2060
+ function getArgumentEffect (
2061
+ signatureEffect : Effect | null ,
2062
+ arg : Place | SpreadPattern ,
2063
+ ) : Effect {
2064
+ if ( signatureEffect != null ) {
2065
+ if ( arg . kind === 'Identifier' ) {
2066
+ return signatureEffect ;
2067
+ } else if (
2068
+ signatureEffect === Effect . Mutate ||
2069
+ signatureEffect === Effect . ConditionallyMutate
2070
+ ) {
2071
+ return signatureEffect ;
2072
+ } else {
2073
+ // see call-spread-argument-mutable-iterator test fixture
2074
+ if ( signatureEffect === Effect . Freeze ) {
2075
+ CompilerError . throwTodo ( {
2076
+ reason : 'Support spread syntax for hook arguments' ,
2077
+ loc : arg . place . loc ,
2078
+ } ) ;
2079
+ }
2080
+ // effects[i] is Effect.Capture | Effect.Read | Effect.Store
2081
+ return Effect . ConditionallyMutate ;
2082
+ }
2083
+ } else {
2084
+ return Effect . ConditionallyMutate ;
2085
+ }
2086
+ }
0 commit comments