@@ -1299,3 +1299,82 @@ g_test_constant() = (f_constant(3) == 3 && f_constant(4) == 4 ? true : "BAD")
1299
1299
1300
1300
f_pure_add () = (1 + 1 == 2 ) ? true : " FAIL"
1301
1301
@test @inferred f_pure_add ()
1302
+
1303
+ # mechanism for spoofing work-limiting heuristics and early generator expansion (#24852)
1304
+ function _generated_stub (gen:: Symbol , args:: Vector{Any} , params:: Vector{Any} , line, file, expand_early)
1305
+ stub = Expr (:new , Core. GeneratedFunctionStub, gen, args, params, line, file, expand_early)
1306
+ return Expr (:meta , :generated , stub)
1307
+ end
1308
+
1309
+ f24852_kernel (x, y) = x * y
1310
+
1311
+ function f24852_kernel_cinfo (x, y)
1312
+ sig, spvals, method = Base. _methods_by_ftype (Tuple{typeof (f24852_kernel),x,y}, - 1 , typemax (UInt))[1 ]
1313
+ code_info = Base. uncompressed_ast (method)
1314
+ body = Expr (:block , code_info. code... )
1315
+ Base. Core. Inference. substitute! (body, 0 , Any[], sig, Any[spvals... ], 0 , :propagate )
1316
+ return method, code_info
1317
+ end
1318
+
1319
+ function f24852_gen_cinfo_uninflated (X, Y, f, x, y)
1320
+ _, code_info = f24852_kernel_cinfo (x, y)
1321
+ return code_info
1322
+ end
1323
+
1324
+ function f24852_gen_cinfo_inflated (X, Y, f, x, y)
1325
+ method, code_info = f24852_kernel_cinfo (x, y)
1326
+ code_info. method_for_inference_heuristics = method
1327
+ return code_info
1328
+ end
1329
+
1330
+ function f24852_gen_expr (X, Y, f, x, y)
1331
+ return :(f24852_kernel (x:: $X , y:: $Y ))
1332
+ end
1333
+
1334
+ @eval begin
1335
+ function f24852_late_expr (x:: X , y:: Y ) where {X, Y}
1336
+ $ (_generated_stub (:f24852_gen_expr , Any[:f24852_late_expr , :x , :y ],
1337
+ Any[:X , :Y ], @__LINE__ , QuoteNode (Symbol (@__FILE__ )), false ))
1338
+ end
1339
+ function f24852_late_inflated (x:: X , y:: Y ) where {X, Y}
1340
+ $ (_generated_stub (:f24852_gen_cinfo_inflated , Any[:f24852_late_inflated , :x , :y ],
1341
+ Any[:X , :Y ], @__LINE__ , QuoteNode (Symbol (@__FILE__ )), false ))
1342
+ end
1343
+ function f24852_late_uninflated (x:: X , y:: Y ) where {X, Y}
1344
+ $ (_generated_stub (:f24852_gen_cinfo_uninflated , Any[:f24852_late_uninflated , :x , :y ],
1345
+ Any[:X , :Y ], @__LINE__ , QuoteNode (Symbol (@__FILE__ )), false ))
1346
+ end
1347
+ end
1348
+
1349
+ @eval begin
1350
+ function f24852_early_expr (x:: X , y:: Y ) where {X, Y}
1351
+ $ (_generated_stub (:f24852_gen_expr , Any[:f24852_early_expr , :x , :y ],
1352
+ Any[:X , :Y ], @__LINE__ , QuoteNode (Symbol (@__FILE__ )), true ))
1353
+ end
1354
+ function f24852_early_inflated (x:: X , y:: Y ) where {X, Y}
1355
+ $ (_generated_stub (:f24852_gen_cinfo_inflated , Any[:f24852_early_inflated , :x , :y ],
1356
+ Any[:X , :Y ], @__LINE__ , QuoteNode (Symbol (@__FILE__ )), true ))
1357
+ end
1358
+ function f24852_early_uninflated (x:: X , y:: Y ) where {X, Y}
1359
+ $ (_generated_stub (:f24852_gen_cinfo_uninflated , Any[:f24852_early_uninflated , :x , :y ],
1360
+ Any[:X , :Y ], @__LINE__ , QuoteNode (Symbol (@__FILE__ )), true ))
1361
+ end
1362
+ end
1363
+
1364
+ x, y = rand (), rand ()
1365
+ result = f24852_kernel (x, y)
1366
+
1367
+ # TODO : The commented out tests here are the ones where `method_for_inference_heuristics`
1368
+ # is inflated; these tests cause segfaults. Probably due to incorrect CodeInfo
1369
+ # construction/initialization happening somewhere...
1370
+
1371
+ @test result === f24852_late_expr (x, y)
1372
+ @test result === f24852_late_uninflated (x, y)
1373
+ # @test result === f24852_late_inflated(x, y)
1374
+
1375
+ @test result === f24852_early_expr (x, y)
1376
+ @test result === f24852_early_uninflated (x, y)
1377
+ # @test result === f24852_early_inflated(x, y)
1378
+
1379
+ # TODO : test that `expand_early = true` + inflated `method_for_inference_heuristics`
1380
+ # can be used to tighten up some inference result.
0 commit comments