From 1ad1e1a7bce0fc3fc9889062f0e1c2ff0b7be0ef Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Thu, 15 Oct 2026 11:15:48 +0200 Subject: [PATCH 1/6] Rust: Document cfg! expansion nodes Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 2b6b35e8-4f05-4cf7-b229-2ddc3ebdd83c --- rust/schema/annotations.py | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/rust/schema/annotations.py b/rust/schema/annotations.py index fc2d81c4ed08..84bae031b4f1 100644 --- a/rust/schema/annotations.py +++ b/rust/schema/annotations.py @@ -552,6 +552,41 @@ class _: """ +@annotate(CfgPredExpr, cfg=True) +class _: + """ + A configuration predicate expression resulting from expansion of a `cfg!` macro call. + It has type `bool` and evaluates to whether the configuration predicate holds. + + Rust-analyzer expands `cfg!(...)` in expression position to its internal `builtin#cfg(...)` + syntax, as illustrated below: + ```rust + builtin#cfg(unix); + builtin#cfg(target_os = "windows"); + builtin#cfg(any(unix, target_os = "windows")); + ``` + """ + + +@annotate(CfgPredPat, cfg=True) +class _: + """ + A configuration predicate pattern resulting from expansion of a `cfg!` macro call. + It matches `true` when the configuration predicate holds and `false` otherwise. + + Rust-analyzer expands `cfg!(...)` in pattern position to its internal `builtin#cfg(...)` + syntax, as illustrated below: + ```rust + match true { + builtin#cfg(unix) => (), + builtin#cfg(target_os = "windows") => (), + builtin#cfg(any(unix, target_os = "windows")) => (), + _ => (), + }; + ``` + """ + + @annotate(ClosureExpr) class _: """ From 63fe1290ce7b5aa27cc47d12c68c85c3a9642f48 Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Thu, 15 Oct 2026 11:15:50 +0200 Subject: [PATCH 2/6] Rust: Regenerate code for cfg! expansion nodes Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 2b6b35e8-4f05-4cf7-b229-2ddc3ebdd83c --- rust/ql/.generated.list | 20 ++++++++-------- rust/ql/.gitattributes | 4 ++-- .../internal/generated/CfgNodes.qll | 23 +++++++++++++++++++ .../lib/codeql/rust/elements/CfgPredExpr.qll | 12 ++++++++++ .../lib/codeql/rust/elements/CfgPredPat.qll | 15 ++++++++++++ .../elements/internal/CfgPredExprImpl.qll | 12 ++++++++++ .../rust/elements/internal/CfgPredPatImpl.qll | 15 ++++++++++++ .../internal/generated/CfgPredExpr.qll | 10 ++++++++ .../internal/generated/CfgPredPat.qll | 13 +++++++++++ .../rust/elements/internal/generated/Raw.qll | 23 +++++++++++++++++++ .../generated/.generated_tests.list | 2 ++ .../extractor-tests/generated/.gitattributes | 2 ++ .../generated/CfgPredExpr/CfgPredExpr.ql | 9 ++++++++ .../generated/CfgPredExpr/MISSING_SOURCE.txt | 4 ---- .../CfgPredExpr/gen_cfg_pred_expr.rs | 12 ++++++++++ .../generated/CfgPredPat/CfgPredPat.ql | 9 ++++++++ .../generated/CfgPredPat/MISSING_SOURCE.txt | 4 ---- .../generated/CfgPredPat/gen_cfg_pred_pat.rs | 15 ++++++++++++ 18 files changed, 184 insertions(+), 20 deletions(-) create mode 100644 rust/ql/test/extractor-tests/generated/CfgPredExpr/CfgPredExpr.ql delete mode 100644 rust/ql/test/extractor-tests/generated/CfgPredExpr/MISSING_SOURCE.txt create mode 100644 rust/ql/test/extractor-tests/generated/CfgPredExpr/gen_cfg_pred_expr.rs create mode 100644 rust/ql/test/extractor-tests/generated/CfgPredPat/CfgPredPat.ql delete mode 100644 rust/ql/test/extractor-tests/generated/CfgPredPat/MISSING_SOURCE.txt create mode 100644 rust/ql/test/extractor-tests/generated/CfgPredPat/gen_cfg_pred_pat.rs diff --git a/rust/ql/.generated.list b/rust/ql/.generated.list index 5c18625dcfd6..0cdb016c2d16 100644 --- a/rust/ql/.generated.list +++ b/rust/ql/.generated.list @@ -1,4 +1,4 @@ -lib/codeql/rust/controlflow/internal/generated/CfgNodes.qll a930796c48512c3d62163b6ab5683109ef10e0f9fa620ea08229ec0430b6c302 377246276407e62bb4b4bceace683a44e8c57beffa444a9c85169bf2455a2d09 +lib/codeql/rust/controlflow/internal/generated/CfgNodes.qll 22e459877a319214e6ba4eb1ed1145df2adbb4b217494e6a12209f2960f87e75 79eb67e02dbece2df4b9008d76aa34bb807832cb1ff9bc32d3a5dff61cfc3465 lib/codeql/rust/elements/Abi.qll 485a2e79f6f7bfd1c02a6e795a71e62dede3c3e150149d5f8f18b761253b7208 6159ba175e7ead0dd2e3f2788f49516c306ee11b1a443bd4bdc00b7017d559bd lib/codeql/rust/elements/Addressable.qll 13011bfd2e1556694c3d440cc34af8527da4df49ad92b62f2939d3699ff2cea5 ddb25935f7553a1a384b1abe2e4b4fa90ab50b952dadec32fd867afcb054f4be lib/codeql/rust/elements/AnyAttr.qll 31536ed6ba02c538ff192089dc40c6f984ce808406f0522eed49539b9ae8a0da c6df96292f0f96415af4e8b3736e870475c21829ab08a8fe56d221ee4bb4cbd7 @@ -39,8 +39,8 @@ lib/codeql/rust/elements/CfgAtom.qll 0567c41550cbcf88f334f0285bac32f87726099f244 lib/codeql/rust/elements/CfgAttrMeta.qll 85f6503abce5c1c3de06df0c0d2ae8fda4206b94bc8103d54550ad2d84a93fb4 af1e7967d7c9c80f1a4725d8a045d645b247f5aa1a3a462a08eea39c4ab4491f lib/codeql/rust/elements/CfgComposite.qll 50f624532b6f6086ac507c294da7dc3a96d4154d70541449c89b4395cbe366a7 6aa0c7a1484b02833b7cc7692018f96dd6724b8f76a1e171171b7f5aac69e3a6 lib/codeql/rust/elements/CfgMeta.qll 583c4561968f787ea1fb7fe8af165273e0f35c2e1efd26364a004edeebee5786 86eca520313dc40b0e523d8941858909c2632eb32c01d74ddb1c524527fbd8eb -lib/codeql/rust/elements/CfgPredExpr.qll b0eccc0093bb78f2bcce86a0e81a9e78e32d403582a723dbbd6f9302e93ee4da 8e75a1b24512955dc23707a8f1766edb04dab444db7dcda6bc7b9f88fc08e5d5 -lib/codeql/rust/elements/CfgPredPat.qll b0f72411ff7a8565154d12a04610358be901cc649ed0f3caaf8ebbceaa13a50d 51c19f38a0d3a7d5dd044a621091293595c32b50d57dd496f61170be94c7f1ff +lib/codeql/rust/elements/CfgPredExpr.qll 9d4a04f440f249b8f86e0cba433f186c5c062d70a14ff14ebd3fa694c89d17bd b70fa1d6569a71976e0e33c17d2cc6b7974404c59bb6ed44ab00500039bb4376 +lib/codeql/rust/elements/CfgPredPat.qll a59d8f02e2aad1b7ca009855ab6bdb36947810c8b1eb2cc9c244f1917b8055ca f3e943de097f82da14bf00b38804f1cbb7b2bbbbc8f011a99bf50f449c29656d lib/codeql/rust/elements/CfgPredicate.qll e86f55f98b8f09fb5da9af550cb6c43089d8deb2e3b83d7e195e9bddc8cf201b ba30cf064ba1236139c8c55bfab204b9256e407db983b42b23319690c7ff5562 lib/codeql/rust/elements/ClosureExpr.qll 69e0b7a7c7a4c348fcada5ad4da22dd2f51747109f856be239cede315a56d695 93400650282e2d4e682b826e9f5f844aa893dda126548e41ea1c703d2bf209ca lib/codeql/rust/elements/Comment.qll e3613664af81b7a6d77466b4c37d723c74cc220121473dd8a0e552db7d9a0b71 108c4ab7455ea70dd0ccdaacb4baae31ba68b81c9f516b4c903aa9aa7db4fbc1 @@ -266,9 +266,9 @@ lib/codeql/rust/elements/internal/CfgCompositeImpl.qll 840a148dc5c4b213ffdaca621 lib/codeql/rust/elements/internal/CfgMetaConstructor.qll 335cb7a36e430b08a12c5548d0a91bbb9a00aaa2f9b0dc7b2fa526882ec0271e 0bd7002f58c1c19c22023d6f03874d84e083e1aa09ec9cac888661d5ad632f6b lib/codeql/rust/elements/internal/CfgMetaImpl.qll 9d820fb4dee32288e467a8b667ba191588381d8ec2a0ce0e5e8645ee437a16a8 5888fb533768a36d94f56f81058aa0d00c4a2c13721af42bdd30628747698bce lib/codeql/rust/elements/internal/CfgPredExprConstructor.qll 2dc5dc48249f69bbb824786fe8ff84258f8aa71d6da2182b67659624a82de672 abb538b0a7907d59e1e1305f8f200d16860a4f8e38a39832f2f3f7668ae3248c -lib/codeql/rust/elements/internal/CfgPredExprImpl.qll 3c1c543492f3a87891efb474d55340c6f4d8104a2253413deac5cd3b2ea04512 d9b61b32a824fe18a03141cd1994352bcd336bb1c2016815b33f93c011b13396 +lib/codeql/rust/elements/internal/CfgPredExprImpl.qll ef87fbc24432d7b735d467dcdee1dc84d77de98be60ffa3ebec9c47a0363e0af eccd8f349e684a8d87683bf39511cdd4bad06a8a6943e9fbba0d625a6608dab5 lib/codeql/rust/elements/internal/CfgPredPatConstructor.qll 33c2b178e02d65dc96bbcbd0fb38781b413b8b7585a2d371e39730be9b45ecfc 6df70c182b75140f6704045cbbfac34c122fec8a791232b8a2f569f9f86008ec -lib/codeql/rust/elements/internal/CfgPredPatImpl.qll 60da1eb785e66d759c4e63ebcf8e2a913afa80e14e3492710dbbe88979cd2837 2fb96fc7248364a67ea167b007c5c5e321cdf30ee07ca55f9d503acc1539c083 +lib/codeql/rust/elements/internal/CfgPredPatImpl.qll 7619be43f0d2080b2db0b6dbd9b73bf2ead575140dc36b5288195ce469332739 7c0a931f97e3f0c70a432d8fe803db7872a25cfb5ef3f06caddfde52cbf750c4 lib/codeql/rust/elements/internal/CfgPredicateImpl.qll 3ba6c6732a7de4df967dd2cb2b4cc99db8aefb2301b75521f1b369052e3a2ec0 c07d4366f98f374f24e235f809946dc513a16203e4c1eb151c8185a5bc79e70d lib/codeql/rust/elements/internal/ClosureExprConstructor.qll a348229d2b25c7ebd43b58461830b7915e92d31ae83436ec831e0c4873f6218a 70a1d2ac33db3ac4da5826b0e8628f2f29a8f9cdfd8e4fd0e488d90ce0031a38 lib/codeql/rust/elements/internal/CommentConstructor.qll 0b4a6a976d667bf7595500dfb91b9cfc87460a501837ba5382d9a8d8321d7736 7d02d8c94a319dc48e7978d5270e33fc5c308d443768ff96b618236d250123f1 @@ -535,8 +535,8 @@ lib/codeql/rust/elements/internal/generated/CfgAtom.qll 1b7672e06fe19c7ba484937c lib/codeql/rust/elements/internal/generated/CfgAttrMeta.qll 4531aaa627f4d44787970f18dfe30b957f51d83ab2396bac436563c40d144ca9 1731ecd335431b0a2ec70403dc1ad7bce1f8e171a4d6b575d340f1d683fa6c92 lib/codeql/rust/elements/internal/generated/CfgComposite.qll 4f30fa0495381774cd7993a38e1fbe94dff63a5742e8b836bbc35987b746df1a 595ff31b5990845085bbb963ba408dd1246aed1952bee2836ad9d92a1da6e4c7 lib/codeql/rust/elements/internal/generated/CfgMeta.qll 7fd8ee49428da70ba1e52bf9017bbe30b690443c26147c77aa9bcffd7d09338d ec4d34dbd1e7ca412ce3d242f1bd6695a5fe9f263d5bc68ce12610facedf3e93 -lib/codeql/rust/elements/internal/generated/CfgPredExpr.qll 6b49616d1f22141b1629b1f31ba1a5f7bb7c41aaaf392b6ae3e2f0a453dec9c5 8528c388962a105e86a936e1c896b890525341d9e7706afa63745b69da30df9a -lib/codeql/rust/elements/internal/generated/CfgPredPat.qll f3def25f9cecf937d8bb21d121307e72cfefdd8c183727b08a223d9fa92a2b77 65b4a37a9fdd0d4bdd129db66be9f44faf6b71113281148e040c40e24d7a6902 +lib/codeql/rust/elements/internal/generated/CfgPredExpr.qll 316ec9ce880a35b3887ebdcedd1ecd9570832b1fb16ae05877fe3d39c8f84d3f 3c5beddb8e7ecc600bb35fe8718b26ed7d6b49067f650dcbe273b2fcf4d34af6 +lib/codeql/rust/elements/internal/generated/CfgPredPat.qll 39f2520f785798428c2c72089dee08e41d26c1db1107f85727bdd77893a59be1 719f0a2f44818f2b44e18a5bba35375d4ad6ce8db920362bcb451196bd74f418 lib/codeql/rust/elements/internal/generated/CfgPredicate.qll 736fe7385e2af5bb86c349bb1b8dd030aef191541f6af24694e3c460b8272f61 4117ee073683eb5fb81bae9e7e49b4ad0991cfcb53e0b7b4160199931a300632 lib/codeql/rust/elements/internal/generated/ClosureExpr.qll 818aff75d86821c670d8ba0720c3270681b3e070140a9c41beab2a811b43eee6 9bf2d1d38f6c4a99d7c058f8ed096141f5ba6a75d2d26a464f0d65ed4e554222 lib/codeql/rust/elements/internal/generated/Comment.qll 9e306a2947185ca15946a3d43dea09d10000b3ba8b28b4691a4b4be6697b7a53 c3df90920fcb595afe5c6e6b614ed0cc61c7679d9785ff17aa0db7cdaedc1115 @@ -644,7 +644,7 @@ lib/codeql/rust/elements/internal/generated/PtrTypeRepr.qll d7a400b238d7edf2b465 lib/codeql/rust/elements/internal/generated/PureSynthConstructors.qll e5b8e69519012bbaae29dcb82d53f7f7ecce368c0358ec27ef6180b228a0057f e5b8e69519012bbaae29dcb82d53f7f7ecce368c0358ec27ef6180b228a0057f lib/codeql/rust/elements/internal/generated/RangeExpr.qll 7a1ff277e5e8a6731d6cb664a09da07cce2bd6ca3541008b381cd5a5a636a15f 2a9d51363a1a55a080d39575c623ba11cb0f259c04f40351fbb5b89358b31aa6 lib/codeql/rust/elements/internal/generated/RangePat.qll a0c805eb31a773e16806384bd11592563c61b720e694bd444b93c28b5cf00d65 4b82088a62e7e5027f5930a697a18b5d4fd2a831a7bb6123d1b3f8ff4a9255ea -lib/codeql/rust/elements/internal/generated/Raw.qll 8aa72bb0695b99843411106a2e433bc2063383b5762634cf310d478b2677a0a3 5ced366f89dc64c9ce347166f2932656d56ba8e8ce2f17c01c446b157905d0bb +lib/codeql/rust/elements/internal/generated/Raw.qll ee4cce08f20a9049128fcaade49d0832a878e41090af41bd5831140e0336b381 01b8e1f4cbc05f49e4abfcdd7481ad9524b3f3d500c9da11529306ae1cd3071b lib/codeql/rust/elements/internal/generated/RefExpr.qll c7b711ac05f7fe8fb97b81b09e794e7756141570265e3a995e40e7c79bb2b49d 11b572508c010e79a7edb0f1b349a4ea3e2fc68f6d7bc3f38fbeacf0c91d68e2 lib/codeql/rust/elements/internal/generated/RefPat.qll 456ede39837463ee22a630ec7ab6c8630d3664a8ea206fcc6e4f199e92fa564c 5622062765f32930465ba6b170e986706f159f6070f48adee3c20e24e8df4e05 lib/codeql/rust/elements/internal/generated/RefTypeRepr.qll fbab8bae4d3eac10338a9bc5743f3ac9c0feab11107d6d28825f4e97bcd59bad 224f6aec466ddcde526ce8df23d2f925887232b462730af078815a68b47c133d @@ -742,8 +742,8 @@ test/extractor-tests/generated/CfgAtom/MISSING_SOURCE.txt b6cf5771fdbbe981aeb3f4 test/extractor-tests/generated/CfgAttrMeta/MISSING_SOURCE.txt b6cf5771fdbbe981aeb3f443ec7a40517b6e99ffc9817fd8872c2e344240dae1 b6cf5771fdbbe981aeb3f443ec7a40517b6e99ffc9817fd8872c2e344240dae1 test/extractor-tests/generated/CfgComposite/MISSING_SOURCE.txt b6cf5771fdbbe981aeb3f443ec7a40517b6e99ffc9817fd8872c2e344240dae1 b6cf5771fdbbe981aeb3f443ec7a40517b6e99ffc9817fd8872c2e344240dae1 test/extractor-tests/generated/CfgMeta/MISSING_SOURCE.txt b6cf5771fdbbe981aeb3f443ec7a40517b6e99ffc9817fd8872c2e344240dae1 b6cf5771fdbbe981aeb3f443ec7a40517b6e99ffc9817fd8872c2e344240dae1 -test/extractor-tests/generated/CfgPredExpr/MISSING_SOURCE.txt b6cf5771fdbbe981aeb3f443ec7a40517b6e99ffc9817fd8872c2e344240dae1 b6cf5771fdbbe981aeb3f443ec7a40517b6e99ffc9817fd8872c2e344240dae1 -test/extractor-tests/generated/CfgPredPat/MISSING_SOURCE.txt b6cf5771fdbbe981aeb3f443ec7a40517b6e99ffc9817fd8872c2e344240dae1 b6cf5771fdbbe981aeb3f443ec7a40517b6e99ffc9817fd8872c2e344240dae1 +test/extractor-tests/generated/CfgPredExpr/CfgPredExpr.ql ee04d84f8da7fbfb60c585e0ca56e6bbb5e06f2e78306c6e594e1c1def39972c e5c5e20e39bda63e5f46a115fbaf8a6b6ac1ea41b4dda438ddea81c498baeddf +test/extractor-tests/generated/CfgPredPat/CfgPredPat.ql 5cbae186f92545bf083c19a35a5b0b5c03d65054047f09ef3065df5718b675f1 22dac46bdd82e5c84f8a1e4bb2b0b864614650978bfc60191258f09f07a0550d test/extractor-tests/generated/ClosureExpr/ClosureExpr.ql 1fe39a8ba8256bcac2d741a74d5414e4e8b329459d1747daf948f57b8d321d19 5e2296d89e386cf4b789ad8afe102d3ede78011224fe6f182b235d1550ec5e6e test/extractor-tests/generated/Comment/Comment.ql 0e0454911d2cf2e7ef5c6d860b84c57b9d490090914ebcf4fa0e8a70f777f066 cbd1c195276ef163f8d3c122344738c884dc9fb70eb2f9b7067829d735d48c4c test/extractor-tests/generated/Const/Const.ql d554b324b7ae3ed9265fea942782adf05bd1e6b7d0b3308b393b2484e4adaf68 2c4aef753236468c2b602f572dabc2fd7d8e2c137536badaba14c08d30475fc2 diff --git a/rust/ql/.gitattributes b/rust/ql/.gitattributes index f0e39bc72b63..3addf5fc652e 100644 --- a/rust/ql/.gitattributes +++ b/rust/ql/.gitattributes @@ -744,8 +744,8 @@ /test/extractor-tests/generated/CfgAttrMeta/MISSING_SOURCE.txt linguist-generated /test/extractor-tests/generated/CfgComposite/MISSING_SOURCE.txt linguist-generated /test/extractor-tests/generated/CfgMeta/MISSING_SOURCE.txt linguist-generated -/test/extractor-tests/generated/CfgPredExpr/MISSING_SOURCE.txt linguist-generated -/test/extractor-tests/generated/CfgPredPat/MISSING_SOURCE.txt linguist-generated +/test/extractor-tests/generated/CfgPredExpr/CfgPredExpr.ql linguist-generated +/test/extractor-tests/generated/CfgPredPat/CfgPredPat.ql linguist-generated /test/extractor-tests/generated/ClosureExpr/ClosureExpr.ql linguist-generated /test/extractor-tests/generated/Comment/Comment.ql linguist-generated /test/extractor-tests/generated/Const/Const.ql linguist-generated diff --git a/rust/ql/lib/codeql/rust/controlflow/internal/generated/CfgNodes.qll b/rust/ql/lib/codeql/rust/controlflow/internal/generated/CfgNodes.qll index 4bac01f686f9..d882de256d97 100644 --- a/rust/ql/lib/codeql/rust/controlflow/internal/generated/CfgNodes.qll +++ b/rust/ql/lib/codeql/rust/controlflow/internal/generated/CfgNodes.qll @@ -781,6 +781,16 @@ module MakeCfgNodes Input> { } /** + * A configuration predicate expression resulting from expansion of a `cfg!` macro call. + * It has type `bool` and evaluates to whether the configuration predicate holds. + * + * Rust-analyzer expands `cfg!(...)` in expression position to its internal `builtin#cfg(...)` + * syntax, as illustrated below: + * ```rust + * builtin#cfg(unix); + * builtin#cfg(target_os = "windows"); + * builtin#cfg(any(unix, target_os = "windows")); + * ``` */ final class CfgPredExprCfgNode extends CfgNodeFinal, ExprCfgNode { private CfgPredExpr node; @@ -806,6 +816,19 @@ module MakeCfgNodes Input> { } /** + * A configuration predicate pattern resulting from expansion of a `cfg!` macro call. + * It matches `true` when the configuration predicate holds and `false` otherwise. + * + * Rust-analyzer expands `cfg!(...)` in pattern position to its internal `builtin#cfg(...)` + * syntax, as illustrated below: + * ```rust + * match true { + * builtin#cfg(unix) => (), + * builtin#cfg(target_os = "windows") => (), + * builtin#cfg(any(unix, target_os = "windows")) => (), + * _ => (), + * }; + * ``` */ final class CfgPredPatCfgNode extends CfgNodeFinal, PatCfgNode { private CfgPredPat node; diff --git a/rust/ql/lib/codeql/rust/elements/CfgPredExpr.qll b/rust/ql/lib/codeql/rust/elements/CfgPredExpr.qll index 955cd49e4c15..ac0c60bc1f70 100644 --- a/rust/ql/lib/codeql/rust/elements/CfgPredExpr.qll +++ b/rust/ql/lib/codeql/rust/elements/CfgPredExpr.qll @@ -7,4 +7,16 @@ private import internal.CfgPredExprImpl import codeql.rust.elements.CfgPredicate import codeql.rust.elements.Expr +/** + * A configuration predicate expression resulting from expansion of a `cfg!` macro call. + * It has type `bool` and evaluates to whether the configuration predicate holds. + * + * Rust-analyzer expands `cfg!(...)` in expression position to its internal `builtin#cfg(...)` + * syntax, as illustrated below: + * ```rust + * builtin#cfg(unix); + * builtin#cfg(target_os = "windows"); + * builtin#cfg(any(unix, target_os = "windows")); + * ``` + */ final class CfgPredExpr = Impl::CfgPredExpr; diff --git a/rust/ql/lib/codeql/rust/elements/CfgPredPat.qll b/rust/ql/lib/codeql/rust/elements/CfgPredPat.qll index 1a6dfe04135b..ee633839aa49 100644 --- a/rust/ql/lib/codeql/rust/elements/CfgPredPat.qll +++ b/rust/ql/lib/codeql/rust/elements/CfgPredPat.qll @@ -7,4 +7,19 @@ private import internal.CfgPredPatImpl import codeql.rust.elements.CfgPredicate import codeql.rust.elements.Pat +/** + * A configuration predicate pattern resulting from expansion of a `cfg!` macro call. + * It matches `true` when the configuration predicate holds and `false` otherwise. + * + * Rust-analyzer expands `cfg!(...)` in pattern position to its internal `builtin#cfg(...)` + * syntax, as illustrated below: + * ```rust + * match true { + * builtin#cfg(unix) => (), + * builtin#cfg(target_os = "windows") => (), + * builtin#cfg(any(unix, target_os = "windows")) => (), + * _ => (), + * }; + * ``` + */ final class CfgPredPat = Impl::CfgPredPat; diff --git a/rust/ql/lib/codeql/rust/elements/internal/CfgPredExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/CfgPredExprImpl.qll index 0dd2a9c0aa0b..b4987870c3da 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/CfgPredExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/CfgPredExprImpl.qll @@ -12,5 +12,17 @@ private import codeql.rust.elements.internal.generated.CfgPredExpr * be referenced directly. */ module Impl { + /** + * A configuration predicate expression resulting from expansion of a `cfg!` macro call. + * It has type `bool` and evaluates to whether the configuration predicate holds. + * + * Rust-analyzer expands `cfg!(...)` in expression position to its internal `builtin#cfg(...)` + * syntax, as illustrated below: + * ```rust + * builtin#cfg(unix); + * builtin#cfg(target_os = "windows"); + * builtin#cfg(any(unix, target_os = "windows")); + * ``` + */ class CfgPredExpr extends Generated::CfgPredExpr { } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/CfgPredPatImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/CfgPredPatImpl.qll index 8cf8e83faeff..ac9e15cf6136 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/CfgPredPatImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/CfgPredPatImpl.qll @@ -12,5 +12,20 @@ private import codeql.rust.elements.internal.generated.CfgPredPat * be referenced directly. */ module Impl { + /** + * A configuration predicate pattern resulting from expansion of a `cfg!` macro call. + * It matches `true` when the configuration predicate holds and `false` otherwise. + * + * Rust-analyzer expands `cfg!(...)` in pattern position to its internal `builtin#cfg(...)` + * syntax, as illustrated below: + * ```rust + * match true { + * builtin#cfg(unix) => (), + * builtin#cfg(target_os = "windows") => (), + * builtin#cfg(any(unix, target_os = "windows")) => (), + * _ => (), + * }; + * ``` + */ class CfgPredPat extends Generated::CfgPredPat { } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/generated/CfgPredExpr.qll b/rust/ql/lib/codeql/rust/elements/internal/generated/CfgPredExpr.qll index 5c2c473c1edd..2800e249b14f 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/generated/CfgPredExpr.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/generated/CfgPredExpr.qll @@ -15,6 +15,16 @@ import codeql.rust.elements.internal.ExprImpl::Impl as ExprImpl */ module Generated { /** + * A configuration predicate expression resulting from expansion of a `cfg!` macro call. + * It has type `bool` and evaluates to whether the configuration predicate holds. + * + * Rust-analyzer expands `cfg!(...)` in expression position to its internal `builtin#cfg(...)` + * syntax, as illustrated below: + * ```rust + * builtin#cfg(unix); + * builtin#cfg(target_os = "windows"); + * builtin#cfg(any(unix, target_os = "windows")); + * ``` * INTERNAL: Do not reference the `Generated::CfgPredExpr` class directly. * Use the subclass `CfgPredExpr`, where the following predicates are available. */ diff --git a/rust/ql/lib/codeql/rust/elements/internal/generated/CfgPredPat.qll b/rust/ql/lib/codeql/rust/elements/internal/generated/CfgPredPat.qll index a6637a55d4aa..53e8410b9691 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/generated/CfgPredPat.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/generated/CfgPredPat.qll @@ -15,6 +15,19 @@ import codeql.rust.elements.internal.PatImpl::Impl as PatImpl */ module Generated { /** + * A configuration predicate pattern resulting from expansion of a `cfg!` macro call. + * It matches `true` when the configuration predicate holds and `false` otherwise. + * + * Rust-analyzer expands `cfg!(...)` in pattern position to its internal `builtin#cfg(...)` + * syntax, as illustrated below: + * ```rust + * match true { + * builtin#cfg(unix) => (), + * builtin#cfg(target_os = "windows") => (), + * builtin#cfg(any(unix, target_os = "windows")) => (), + * _ => (), + * }; + * ``` * INTERNAL: Do not reference the `Generated::CfgPredPat` class directly. * Use the subclass `CfgPredPat`, where the following predicates are available. */ diff --git a/rust/ql/lib/codeql/rust/elements/internal/generated/Raw.qll b/rust/ql/lib/codeql/rust/elements/internal/generated/Raw.qll index e05baeebf6f0..284d1cc4c4b1 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/generated/Raw.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/generated/Raw.qll @@ -3295,6 +3295,16 @@ module Raw { /** * INTERNAL: Do not use. + * A configuration predicate expression resulting from expansion of a `cfg!` macro call. + * It has type `bool` and evaluates to whether the configuration predicate holds. + * + * Rust-analyzer expands `cfg!(...)` in expression position to its internal `builtin#cfg(...)` + * syntax, as illustrated below: + * ```rust + * builtin#cfg(unix); + * builtin#cfg(target_os = "windows"); + * builtin#cfg(any(unix, target_os = "windows")); + * ``` */ class CfgPredExpr extends @cfg_pred_expr, Expr { override string toString() { result = "CfgPredExpr" } @@ -3319,6 +3329,19 @@ module Raw { /** * INTERNAL: Do not use. + * A configuration predicate pattern resulting from expansion of a `cfg!` macro call. + * It matches `true` when the configuration predicate holds and `false` otherwise. + * + * Rust-analyzer expands `cfg!(...)` in pattern position to its internal `builtin#cfg(...)` + * syntax, as illustrated below: + * ```rust + * match true { + * builtin#cfg(unix) => (), + * builtin#cfg(target_os = "windows") => (), + * builtin#cfg(any(unix, target_os = "windows")) => (), + * _ => (), + * }; + * ``` */ class CfgPredPat extends @cfg_pred_pat, Pat { override string toString() { result = "CfgPredPat" } diff --git a/rust/ql/test/extractor-tests/generated/.generated_tests.list b/rust/ql/test/extractor-tests/generated/.generated_tests.list index c2efb431fe12..c21b0d493bad 100644 --- a/rust/ql/test/extractor-tests/generated/.generated_tests.list +++ b/rust/ql/test/extractor-tests/generated/.generated_tests.list @@ -25,6 +25,8 @@ BoxPat/gen_box_pat.rs 1493e24b732370b577ade38c47db17fa157df19f5390606a67a6040e49 BreakExpr/gen_break_expr.rs aacdf9df7fc51d19742b9e813835c0bd0913017e8d62765960e06b27d58b9031 aacdf9df7fc51d19742b9e813835c0bd0913017e8d62765960e06b27d58b9031 CallExpr/gen_call_expr.rs 228705e9b0c46d34aa035da3c139a8c3e93fb144d3310592d5bad38ac97382c2 228705e9b0c46d34aa035da3c139a8c3e93fb144d3310592d5bad38ac97382c2 CastExpr/gen_cast_expr.rs c3892211fbae4fed7cb1f25ff1679fd79d2878bf0bf2bd4b7982af23d00129f5 c3892211fbae4fed7cb1f25ff1679fd79d2878bf0bf2bd4b7982af23d00129f5 +CfgPredExpr/gen_cfg_pred_expr.rs fd4a01de87225132c7c6de4d0014a2dc56ab253697464c9da7a16213a5c3fe5b fd4a01de87225132c7c6de4d0014a2dc56ab253697464c9da7a16213a5c3fe5b +CfgPredPat/gen_cfg_pred_pat.rs a764f03c829993cb7fa3791c67cd0cdd394983486a3c86d75ced251658cc8b5a a764f03c829993cb7fa3791c67cd0cdd394983486a3c86d75ced251658cc8b5a ClosureExpr/gen_closure_expr.rs bd95408103b7f2084e526e6d35cf3319b2e9d7219aff4c80e4e6691180c549b4 bd95408103b7f2084e526e6d35cf3319b2e9d7219aff4c80e4e6691180c549b4 Comment/gen_comment.rs cfe4ffad0c027a138894f6730e754ece90e0ecd38efc8d893aba966024d6153b cfe4ffad0c027a138894f6730e754ece90e0ecd38efc8d893aba966024d6153b Const/gen_const.rs a3b971134a4204d0da12563fcefa9ab72f3f2f2e957e82b70c8548b5807f375f a3b971134a4204d0da12563fcefa9ab72f3f2f2e957e82b70c8548b5807f375f diff --git a/rust/ql/test/extractor-tests/generated/.gitattributes b/rust/ql/test/extractor-tests/generated/.gitattributes index b70a7552e136..04681384c1b2 100644 --- a/rust/ql/test/extractor-tests/generated/.gitattributes +++ b/rust/ql/test/extractor-tests/generated/.gitattributes @@ -27,6 +27,8 @@ /BreakExpr/gen_break_expr.rs linguist-generated /CallExpr/gen_call_expr.rs linguist-generated /CastExpr/gen_cast_expr.rs linguist-generated +/CfgPredExpr/gen_cfg_pred_expr.rs linguist-generated +/CfgPredPat/gen_cfg_pred_pat.rs linguist-generated /ClosureExpr/gen_closure_expr.rs linguist-generated /Comment/gen_comment.rs linguist-generated /Const/gen_const.rs linguist-generated diff --git a/rust/ql/test/extractor-tests/generated/CfgPredExpr/CfgPredExpr.ql b/rust/ql/test/extractor-tests/generated/CfgPredExpr/CfgPredExpr.ql new file mode 100644 index 000000000000..ee144ebfda76 --- /dev/null +++ b/rust/ql/test/extractor-tests/generated/CfgPredExpr/CfgPredExpr.ql @@ -0,0 +1,9 @@ +// generated by codegen, do not edit +import codeql.rust.elements +import TestUtils + +query predicate instances(CfgPredExpr x) { toBeTested(x) and not x.isUnknown() } + +query predicate getCfgPredicate(CfgPredExpr x, CfgPredicate getCfgPredicate) { + toBeTested(x) and not x.isUnknown() and getCfgPredicate = x.getCfgPredicate() +} diff --git a/rust/ql/test/extractor-tests/generated/CfgPredExpr/MISSING_SOURCE.txt b/rust/ql/test/extractor-tests/generated/CfgPredExpr/MISSING_SOURCE.txt deleted file mode 100644 index 7f96b17b1f3c..000000000000 --- a/rust/ql/test/extractor-tests/generated/CfgPredExpr/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen, do not edit - -After a source file is added in this directory and codegen is run again, test queries -will appear and this file will be deleted diff --git a/rust/ql/test/extractor-tests/generated/CfgPredExpr/gen_cfg_pred_expr.rs b/rust/ql/test/extractor-tests/generated/CfgPredExpr/gen_cfg_pred_expr.rs new file mode 100644 index 000000000000..47eb51d6165a --- /dev/null +++ b/rust/ql/test/extractor-tests/generated/CfgPredExpr/gen_cfg_pred_expr.rs @@ -0,0 +1,12 @@ +// generated by codegen, do not edit + +fn test_cfg_pred_expr() -> () { + // A configuration predicate expression resulting from expansion of a `cfg!` macro call. + // It has type `bool` and evaluates to whether the configuration predicate holds. + // + // Rust-analyzer expands `cfg!(...)` in expression position to its internal `builtin#cfg(...)` + // syntax, as illustrated below: + builtin#cfg(unix); + builtin#cfg(target_os = "windows"); + builtin#cfg(any(unix, target_os = "windows")); +} diff --git a/rust/ql/test/extractor-tests/generated/CfgPredPat/CfgPredPat.ql b/rust/ql/test/extractor-tests/generated/CfgPredPat/CfgPredPat.ql new file mode 100644 index 000000000000..9b2a926a7553 --- /dev/null +++ b/rust/ql/test/extractor-tests/generated/CfgPredPat/CfgPredPat.ql @@ -0,0 +1,9 @@ +// generated by codegen, do not edit +import codeql.rust.elements +import TestUtils + +query predicate instances(CfgPredPat x) { toBeTested(x) and not x.isUnknown() } + +query predicate getCfgPredicate(CfgPredPat x, CfgPredicate getCfgPredicate) { + toBeTested(x) and not x.isUnknown() and getCfgPredicate = x.getCfgPredicate() +} diff --git a/rust/ql/test/extractor-tests/generated/CfgPredPat/MISSING_SOURCE.txt b/rust/ql/test/extractor-tests/generated/CfgPredPat/MISSING_SOURCE.txt deleted file mode 100644 index 7f96b17b1f3c..000000000000 --- a/rust/ql/test/extractor-tests/generated/CfgPredPat/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen, do not edit - -After a source file is added in this directory and codegen is run again, test queries -will appear and this file will be deleted diff --git a/rust/ql/test/extractor-tests/generated/CfgPredPat/gen_cfg_pred_pat.rs b/rust/ql/test/extractor-tests/generated/CfgPredPat/gen_cfg_pred_pat.rs new file mode 100644 index 000000000000..560004dd3cc5 --- /dev/null +++ b/rust/ql/test/extractor-tests/generated/CfgPredPat/gen_cfg_pred_pat.rs @@ -0,0 +1,15 @@ +// generated by codegen, do not edit + +fn test_cfg_pred_pat() -> () { + // A configuration predicate pattern resulting from expansion of a `cfg!` macro call. + // It matches `true` when the configuration predicate holds and `false` otherwise. + // + // Rust-analyzer expands `cfg!(...)` in pattern position to its internal `builtin#cfg(...)` + // syntax, as illustrated below: + match true { + builtin#cfg(unix) => (), + builtin#cfg(target_os = "windows") => (), + builtin#cfg(any(unix, target_os = "windows")) => (), + _ => (), + }; +} From 052953cb6364abe92defd66914503c03b18ca215 Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Thu, 15 Oct 2026 11:15:52 +0200 Subject: [PATCH 3/6] Rust: Add extractor expectations for cfg! expansion nodes Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 2b6b35e8-4f05-4cf7-b229-2ddc3ebdd83c --- .../generated/CfgPredExpr/CfgPredExpr.expected | 8 ++++++++ .../generated/CfgPredPat/CfgPredPat.expected | 8 ++++++++ 2 files changed, 16 insertions(+) create mode 100644 rust/ql/test/extractor-tests/generated/CfgPredExpr/CfgPredExpr.expected create mode 100644 rust/ql/test/extractor-tests/generated/CfgPredPat/CfgPredPat.expected diff --git a/rust/ql/test/extractor-tests/generated/CfgPredExpr/CfgPredExpr.expected b/rust/ql/test/extractor-tests/generated/CfgPredExpr/CfgPredExpr.expected new file mode 100644 index 000000000000..07ebd398df5e --- /dev/null +++ b/rust/ql/test/extractor-tests/generated/CfgPredExpr/CfgPredExpr.expected @@ -0,0 +1,8 @@ +instances +| gen_cfg_pred_expr.rs:9:5:9:21 | CfgPredExpr | +| gen_cfg_pred_expr.rs:10:5:10:38 | CfgPredExpr | +| gen_cfg_pred_expr.rs:11:5:11:49 | CfgPredExpr | +getCfgPredicate +| gen_cfg_pred_expr.rs:9:5:9:21 | CfgPredExpr | gen_cfg_pred_expr.rs:9:17:9:20 | CfgAtom | +| gen_cfg_pred_expr.rs:10:5:10:38 | CfgPredExpr | gen_cfg_pred_expr.rs:10:17:10:37 | CfgAtom | +| gen_cfg_pred_expr.rs:11:5:11:49 | CfgPredExpr | gen_cfg_pred_expr.rs:11:17:11:48 | CfgComposite | diff --git a/rust/ql/test/extractor-tests/generated/CfgPredPat/CfgPredPat.expected b/rust/ql/test/extractor-tests/generated/CfgPredPat/CfgPredPat.expected new file mode 100644 index 000000000000..0edd3716bed6 --- /dev/null +++ b/rust/ql/test/extractor-tests/generated/CfgPredPat/CfgPredPat.expected @@ -0,0 +1,8 @@ +instances +| gen_cfg_pred_pat.rs:10:9:10:25 | CfgPredPat | +| gen_cfg_pred_pat.rs:11:9:11:42 | CfgPredPat | +| gen_cfg_pred_pat.rs:12:9:12:53 | CfgPredPat | +getCfgPredicate +| gen_cfg_pred_pat.rs:10:9:10:25 | CfgPredPat | gen_cfg_pred_pat.rs:10:21:10:24 | CfgAtom | +| gen_cfg_pred_pat.rs:11:9:11:42 | CfgPredPat | gen_cfg_pred_pat.rs:11:21:11:41 | CfgAtom | +| gen_cfg_pred_pat.rs:12:9:12:53 | CfgPredPat | gen_cfg_pred_pat.rs:12:21:12:52 | CfgComposite | From 4346178068f810522e01b67ec7a26ecb65c98986 Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Thu, 15 Oct 2026 11:15:54 +0200 Subject: [PATCH 4/6] Rust: Add type inference regression tests for cfg! Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 2b6b35e8-4f05-4cf7-b229-2ddc3ebdd83c --- .../ql/test/library-tests/type-inference/cfg.rs | 17 +++++++++++++++++ .../type-inference/type-inference.expected | 12 ++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 rust/ql/test/library-tests/type-inference/cfg.rs diff --git a/rust/ql/test/library-tests/type-inference/cfg.rs b/rust/ql/test/library-tests/type-inference/cfg.rs new file mode 100644 index 000000000000..ae6794caa91f --- /dev/null +++ b/rust/ql/test/library-tests/type-inference/cfg.rs @@ -0,0 +1,17 @@ +pub fn expressions() { + let unix = cfg!(unix); // $ MISSING: certainType=unix:bool + let windows = cfg!(target_os = "windows"); // $ MISSING: certainType=windows:bool + let either = cfg!(any(unix, target_os = "windows")); // $ MISSING: certainType=either:bool + let always = cfg!(all()); // $ MISSING: certainType=always:bool + let never = cfg!(any()); // $ MISSING: certainType=never:bool +} + +pub fn patterns() { + let value = Default::default(); // $ MISSING: target=default type=value:bool + match value { + cfg!(unix) => (), + cfg!(target_os = "windows") => (), + cfg!(any(unix, target_os = "windows")) => (), + _ => (), + } +} diff --git a/rust/ql/test/library-tests/type-inference/type-inference.expected b/rust/ql/test/library-tests/type-inference/type-inference.expected index b519e18357b3..e0681dd05aa2 100644 --- a/rust/ql/test/library-tests/type-inference/type-inference.expected +++ b/rust/ql/test/library-tests/type-inference/type-inference.expected @@ -508,6 +508,11 @@ inferCertainType | blanket_impl.rs:299:44:299:44 | c | | blanket_impl.rs:286:5:286:29 | MySqlConnection | | blanket_impl.rs:299:47:299:67 | "SELECT * FROM users" | | {EXTERNAL LOCATION} | & | | blanket_impl.rs:299:47:299:67 | "SELECT * FROM users" | TRef | {EXTERNAL LOCATION} | str | +| cfg.rs:1:22:7:1 | { ... } | | {EXTERNAL LOCATION} | () | +| cfg.rs:12:23:12:24 | TupleExpr | | {EXTERNAL LOCATION} | () | +| cfg.rs:13:40:13:41 | TupleExpr | | {EXTERNAL LOCATION} | () | +| cfg.rs:14:51:14:52 | TupleExpr | | {EXTERNAL LOCATION} | () | +| cfg.rs:15:14:15:15 | TupleExpr | | {EXTERNAL LOCATION} | () | | closure.rs:4:19:39:5 | { ... } | | {EXTERNAL LOCATION} | () | | closure.rs:6:13:6:22 | my_closure | | {EXTERNAL LOCATION} | dyn Fn | | closure.rs:6:13:6:22 | my_closure | dyn(Args) | {EXTERNAL LOCATION} | (T_2) | @@ -6003,6 +6008,13 @@ inferType | blanket_impl.rs:299:44:299:44 | c | | blanket_impl.rs:286:5:286:29 | MySqlConnection | | blanket_impl.rs:299:47:299:67 | "SELECT * FROM users" | | {EXTERNAL LOCATION} | & | | blanket_impl.rs:299:47:299:67 | "SELECT * FROM users" | TRef | {EXTERNAL LOCATION} | str | +| cfg.rs:1:22:7:1 | { ... } | | {EXTERNAL LOCATION} | () | +| cfg.rs:9:19:17:1 | { ... } | | {EXTERNAL LOCATION} | () | +| cfg.rs:11:5:16:5 | match value { ... } | | {EXTERNAL LOCATION} | () | +| cfg.rs:12:23:12:24 | TupleExpr | | {EXTERNAL LOCATION} | () | +| cfg.rs:13:40:13:41 | TupleExpr | | {EXTERNAL LOCATION} | () | +| cfg.rs:14:51:14:52 | TupleExpr | | {EXTERNAL LOCATION} | () | +| cfg.rs:15:14:15:15 | TupleExpr | | {EXTERNAL LOCATION} | () | | closure.rs:4:19:39:5 | { ... } | | {EXTERNAL LOCATION} | () | | closure.rs:6:13:6:22 | my_closure | | {EXTERNAL LOCATION} | dyn Fn | | closure.rs:6:13:6:22 | my_closure | dyn(Args) | {EXTERNAL LOCATION} | (T_2) | From efaf8313fb3db793765003c63340a84ca8d1350c Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Thu, 15 Oct 2026 11:15:56 +0200 Subject: [PATCH 5/6] Rust: Infer Boolean types for cfg! expressions and patterns Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 2b6b35e8-4f05-4cf7-b229-2ddc3ebdd83c --- .../internal/typeinference/TypeInference.qll | 4 ++ .../test/library-tests/type-inference/cfg.rs | 12 ++--- .../type-inference/type-inference.expected | 46 +++++++++++++++++++ 3 files changed, 56 insertions(+), 6 deletions(-) diff --git a/rust/ql/lib/codeql/rust/internal/typeinference/TypeInference.qll b/rust/ql/lib/codeql/rust/internal/typeinference/TypeInference.qll index 4ee73c2b21fb..7f3a0ae0c282 100644 --- a/rust/ql/lib/codeql/rust/internal/typeinference/TypeInference.qll +++ b/rust/ql/lib/codeql/rust/internal/typeinference/TypeInference.qll @@ -3119,6 +3119,10 @@ private module Input3 implements InputSig3 { Type inferTypeCertainLanguageSpecific(AstNode n, TypePath path) { result = inferLiteralType(n, path, true) or + (n instanceof CfgPredExpr or n instanceof CfgPredPat) and + path.isEmpty() and + result instanceof BoolType + or result = inferRefPatType(n) and path.isEmpty() or diff --git a/rust/ql/test/library-tests/type-inference/cfg.rs b/rust/ql/test/library-tests/type-inference/cfg.rs index ae6794caa91f..59019b739d74 100644 --- a/rust/ql/test/library-tests/type-inference/cfg.rs +++ b/rust/ql/test/library-tests/type-inference/cfg.rs @@ -1,13 +1,13 @@ pub fn expressions() { - let unix = cfg!(unix); // $ MISSING: certainType=unix:bool - let windows = cfg!(target_os = "windows"); // $ MISSING: certainType=windows:bool - let either = cfg!(any(unix, target_os = "windows")); // $ MISSING: certainType=either:bool - let always = cfg!(all()); // $ MISSING: certainType=always:bool - let never = cfg!(any()); // $ MISSING: certainType=never:bool + let unix = cfg!(unix); // $ certainType=unix:bool + let windows = cfg!(target_os = "windows"); // $ certainType=windows:bool + let either = cfg!(any(unix, target_os = "windows")); // $ certainType=either:bool + let always = cfg!(all()); // $ certainType=always:bool + let never = cfg!(any()); // $ certainType=never:bool } pub fn patterns() { - let value = Default::default(); // $ MISSING: target=default type=value:bool + let value = Default::default(); // $ target=default type=value:bool match value { cfg!(unix) => (), cfg!(target_os = "windows") => (), diff --git a/rust/ql/test/library-tests/type-inference/type-inference.expected b/rust/ql/test/library-tests/type-inference/type-inference.expected index e0681dd05aa2..2e8352e06195 100644 --- a/rust/ql/test/library-tests/type-inference/type-inference.expected +++ b/rust/ql/test/library-tests/type-inference/type-inference.expected @@ -509,8 +509,29 @@ inferCertainType | blanket_impl.rs:299:47:299:67 | "SELECT * FROM users" | | {EXTERNAL LOCATION} | & | | blanket_impl.rs:299:47:299:67 | "SELECT * FROM users" | TRef | {EXTERNAL LOCATION} | str | | cfg.rs:1:22:7:1 | { ... } | | {EXTERNAL LOCATION} | () | +| cfg.rs:2:9:2:12 | unix | | {EXTERNAL LOCATION} | bool | +| cfg.rs:2:16:2:25 | MacroExpr | | {EXTERNAL LOCATION} | bool | +| cfg.rs:2:20:2:25 | CfgPredExpr | | {EXTERNAL LOCATION} | bool | +| cfg.rs:3:9:3:15 | windows | | {EXTERNAL LOCATION} | bool | +| cfg.rs:3:19:3:45 | MacroExpr | | {EXTERNAL LOCATION} | bool | +| cfg.rs:3:23:3:45 | CfgPredExpr | | {EXTERNAL LOCATION} | bool | +| cfg.rs:4:9:4:14 | either | | {EXTERNAL LOCATION} | bool | +| cfg.rs:4:18:4:55 | MacroExpr | | {EXTERNAL LOCATION} | bool | +| cfg.rs:4:22:4:55 | CfgPredExpr | | {EXTERNAL LOCATION} | bool | +| cfg.rs:5:9:5:14 | always | | {EXTERNAL LOCATION} | bool | +| cfg.rs:5:18:5:28 | MacroExpr | | {EXTERNAL LOCATION} | bool | +| cfg.rs:5:22:5:28 | CfgPredExpr | | {EXTERNAL LOCATION} | bool | +| cfg.rs:6:9:6:13 | never | | {EXTERNAL LOCATION} | bool | +| cfg.rs:6:17:6:27 | MacroExpr | | {EXTERNAL LOCATION} | bool | +| cfg.rs:6:21:6:27 | CfgPredExpr | | {EXTERNAL LOCATION} | bool | +| cfg.rs:12:9:12:18 | MacroPat | | {EXTERNAL LOCATION} | bool | +| cfg.rs:12:13:12:18 | CfgPredPat | | {EXTERNAL LOCATION} | bool | | cfg.rs:12:23:12:24 | TupleExpr | | {EXTERNAL LOCATION} | () | +| cfg.rs:13:9:13:35 | MacroPat | | {EXTERNAL LOCATION} | bool | +| cfg.rs:13:13:13:35 | CfgPredPat | | {EXTERNAL LOCATION} | bool | | cfg.rs:13:40:13:41 | TupleExpr | | {EXTERNAL LOCATION} | () | +| cfg.rs:14:9:14:46 | MacroPat | | {EXTERNAL LOCATION} | bool | +| cfg.rs:14:13:14:46 | CfgPredPat | | {EXTERNAL LOCATION} | bool | | cfg.rs:14:51:14:52 | TupleExpr | | {EXTERNAL LOCATION} | () | | cfg.rs:15:14:15:15 | TupleExpr | | {EXTERNAL LOCATION} | () | | closure.rs:4:19:39:5 | { ... } | | {EXTERNAL LOCATION} | () | @@ -6009,11 +6030,36 @@ inferType | blanket_impl.rs:299:47:299:67 | "SELECT * FROM users" | | {EXTERNAL LOCATION} | & | | blanket_impl.rs:299:47:299:67 | "SELECT * FROM users" | TRef | {EXTERNAL LOCATION} | str | | cfg.rs:1:22:7:1 | { ... } | | {EXTERNAL LOCATION} | () | +| cfg.rs:2:9:2:12 | unix | | {EXTERNAL LOCATION} | bool | +| cfg.rs:2:16:2:25 | MacroExpr | | {EXTERNAL LOCATION} | bool | +| cfg.rs:2:20:2:25 | CfgPredExpr | | {EXTERNAL LOCATION} | bool | +| cfg.rs:3:9:3:15 | windows | | {EXTERNAL LOCATION} | bool | +| cfg.rs:3:19:3:45 | MacroExpr | | {EXTERNAL LOCATION} | bool | +| cfg.rs:3:23:3:45 | CfgPredExpr | | {EXTERNAL LOCATION} | bool | +| cfg.rs:4:9:4:14 | either | | {EXTERNAL LOCATION} | bool | +| cfg.rs:4:18:4:55 | MacroExpr | | {EXTERNAL LOCATION} | bool | +| cfg.rs:4:22:4:55 | CfgPredExpr | | {EXTERNAL LOCATION} | bool | +| cfg.rs:5:9:5:14 | always | | {EXTERNAL LOCATION} | bool | +| cfg.rs:5:18:5:28 | MacroExpr | | {EXTERNAL LOCATION} | bool | +| cfg.rs:5:22:5:28 | CfgPredExpr | | {EXTERNAL LOCATION} | bool | +| cfg.rs:6:9:6:13 | never | | {EXTERNAL LOCATION} | bool | +| cfg.rs:6:17:6:27 | MacroExpr | | {EXTERNAL LOCATION} | bool | +| cfg.rs:6:21:6:27 | CfgPredExpr | | {EXTERNAL LOCATION} | bool | | cfg.rs:9:19:17:1 | { ... } | | {EXTERNAL LOCATION} | () | +| cfg.rs:10:9:10:13 | value | | {EXTERNAL LOCATION} | bool | +| cfg.rs:10:17:10:34 | ...::default(...) | | {EXTERNAL LOCATION} | bool | | cfg.rs:11:5:16:5 | match value { ... } | | {EXTERNAL LOCATION} | () | +| cfg.rs:11:11:11:15 | value | | {EXTERNAL LOCATION} | bool | +| cfg.rs:12:9:12:18 | MacroPat | | {EXTERNAL LOCATION} | bool | +| cfg.rs:12:13:12:18 | CfgPredPat | | {EXTERNAL LOCATION} | bool | | cfg.rs:12:23:12:24 | TupleExpr | | {EXTERNAL LOCATION} | () | +| cfg.rs:13:9:13:35 | MacroPat | | {EXTERNAL LOCATION} | bool | +| cfg.rs:13:13:13:35 | CfgPredPat | | {EXTERNAL LOCATION} | bool | | cfg.rs:13:40:13:41 | TupleExpr | | {EXTERNAL LOCATION} | () | +| cfg.rs:14:9:14:46 | MacroPat | | {EXTERNAL LOCATION} | bool | +| cfg.rs:14:13:14:46 | CfgPredPat | | {EXTERNAL LOCATION} | bool | | cfg.rs:14:51:14:52 | TupleExpr | | {EXTERNAL LOCATION} | () | +| cfg.rs:15:9:15:9 | _ | | {EXTERNAL LOCATION} | bool | | cfg.rs:15:14:15:15 | TupleExpr | | {EXTERNAL LOCATION} | () | | closure.rs:4:19:39:5 | { ... } | | {EXTERNAL LOCATION} | () | | closure.rs:6:13:6:22 | my_closure | | {EXTERNAL LOCATION} | dyn Fn | From 15cacb0833c9734ccd26200ea2c4428556318096 Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Thu, 15 Oct 2026 13:54:57 +0200 Subject: [PATCH 6/6] Rust: Implement cfg for CfgPredExpr and CfgPredPat Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 2b6b35e8-4f05-4cf7-b229-2ddc3ebdd83c --- .../internal/ControlFlowGraphImpl.qll | 4 ++++ .../controlflow/BasicBlocks.expected | 21 +++++++++++++++++++ .../library-tests/controlflow/Cfg.expected | 21 +++++++++++++++++++ rust/ql/test/library-tests/controlflow/cfg.rs | 10 +++++++++ 4 files changed, 56 insertions(+) create mode 100644 rust/ql/test/library-tests/controlflow/cfg.rs diff --git a/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll b/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll index e7f3c2a4b084..03c00f0bf3dc 100644 --- a/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll +++ b/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll @@ -380,6 +380,8 @@ module ExprTrees { class LiteralExprTree extends LeafTree instanceof LiteralExpr { } + class CfgPredExprTree extends LeafTree instanceof CfgPredExpr { } + abstract class LoopingExprTree extends PostOrderTree { override predicate propagatesAbnormal(AstNode child) { child = this.getLoopBody() } @@ -630,6 +632,8 @@ module PatternTrees { class RestPatTree extends LeafTree, RestPat { } + class CfgPredPatTree extends LeafTree, CfgPredPat { } + class LiteralPatTree extends StandardPostOrderTree, LiteralPat { override AstNode getChildNode(int i) { i = 0 and result = this.getLiteral() } } diff --git a/rust/ql/test/library-tests/controlflow/BasicBlocks.expected b/rust/ql/test/library-tests/controlflow/BasicBlocks.expected index 94760d6875e1..99d1fce9e2c7 100644 --- a/rust/ql/test/library-tests/controlflow/BasicBlocks.expected +++ b/rust/ql/test/library-tests/controlflow/BasicBlocks.expected @@ -1,4 +1,12 @@ dominates +| cfg.rs:1:1:3:1 | enter fn cfg_expr | cfg.rs:1:1:3:1 | enter fn cfg_expr | +| cfg.rs:5:1:10:1 | enter fn cfg_pat | cfg.rs:5:1:10:1 | enter fn cfg_pat | +| cfg.rs:5:1:10:1 | enter fn cfg_pat | cfg.rs:6:5:9:5 | match value { ... } | +| cfg.rs:5:1:10:1 | enter fn cfg_pat | cfg.rs:7:23:7:26 | true | +| cfg.rs:5:1:10:1 | enter fn cfg_pat | cfg.rs:8:9:8:9 | _ | +| cfg.rs:6:5:9:5 | match value { ... } | cfg.rs:6:5:9:5 | match value { ... } | +| cfg.rs:7:23:7:26 | true | cfg.rs:7:23:7:26 | true | +| cfg.rs:8:9:8:9 | _ | cfg.rs:8:9:8:9 | _ | | test.rs:5:5:8:5 | enter fn function_call | test.rs:5:5:8:5 | enter fn function_call | | test.rs:10:5:13:5 | enter fn method_call | test.rs:10:5:13:5 | enter fn method_call | | test.rs:18:5:24:5 | enter fn next | test.rs:18:5:24:5 | enter fn next | @@ -783,6 +791,14 @@ dominates | test.rs:615:5:617:5 | enter fn negated | test.rs:615:5:617:5 | enter fn negated | | test.rs:619:5:621:5 | enter fn multifly_add | test.rs:619:5:621:5 | enter fn multifly_add | postDominance +| cfg.rs:1:1:3:1 | enter fn cfg_expr | cfg.rs:1:1:3:1 | enter fn cfg_expr | +| cfg.rs:5:1:10:1 | enter fn cfg_pat | cfg.rs:5:1:10:1 | enter fn cfg_pat | +| cfg.rs:6:5:9:5 | match value { ... } | cfg.rs:5:1:10:1 | enter fn cfg_pat | +| cfg.rs:6:5:9:5 | match value { ... } | cfg.rs:6:5:9:5 | match value { ... } | +| cfg.rs:6:5:9:5 | match value { ... } | cfg.rs:7:23:7:26 | true | +| cfg.rs:6:5:9:5 | match value { ... } | cfg.rs:8:9:8:9 | _ | +| cfg.rs:7:23:7:26 | true | cfg.rs:7:23:7:26 | true | +| cfg.rs:8:9:8:9 | _ | cfg.rs:8:9:8:9 | _ | | test.rs:5:5:8:5 | enter fn function_call | test.rs:5:5:8:5 | enter fn function_call | | test.rs:10:5:13:5 | enter fn method_call | test.rs:10:5:13:5 | enter fn method_call | | test.rs:18:5:24:5 | enter fn next | test.rs:18:5:24:5 | enter fn next | @@ -1463,6 +1479,9 @@ postDominance | test.rs:615:5:617:5 | enter fn negated | test.rs:615:5:617:5 | enter fn negated | | test.rs:619:5:621:5 | enter fn multifly_add | test.rs:619:5:621:5 | enter fn multifly_add | immediateDominator +| cfg.rs:6:5:9:5 | match value { ... } | cfg.rs:5:1:10:1 | enter fn cfg_pat | +| cfg.rs:7:23:7:26 | true | cfg.rs:5:1:10:1 | enter fn cfg_pat | +| cfg.rs:8:9:8:9 | _ | cfg.rs:5:1:10:1 | enter fn cfg_pat | | test.rs:19:9:23:9 | if ... {...} else {...} | test.rs:18:5:24:5 | enter fn next | | test.rs:20:13:20:13 | n | test.rs:18:5:24:5 | enter fn next | | test.rs:22:13:22:13 | 3 | test.rs:18:5:24:5 | enter fn next | @@ -2087,6 +2106,8 @@ successor | test.rs:571:9:573:9 | if ... {...} | test.rs:575:9:577:9 | if ... {...} | false | | test.rs:571:9:573:9 | if ... {...} | test.rs:576:13:576:27 | ExprStmt | true | joinBlockPredecessor +| cfg.rs:6:5:9:5 | match value { ... } | cfg.rs:7:23:7:26 | true | 0 | +| cfg.rs:6:5:9:5 | match value { ... } | cfg.rs:8:9:8:9 | _ | 1 | | test.rs:19:9:23:9 | if ... {...} else {...} | test.rs:20:13:20:13 | n | 1 | | test.rs:19:9:23:9 | if ... {...} else {...} | test.rs:22:13:22:13 | 3 | 0 | | test.rs:26:5:42:5 | exit fn test_break_and_continue (normal) | test.rs:31:17:31:29 | ExprStmt | 0 | diff --git a/rust/ql/test/library-tests/controlflow/Cfg.expected b/rust/ql/test/library-tests/controlflow/Cfg.expected index 7517c8be81f5..b5b97f21e8f5 100644 --- a/rust/ql/test/library-tests/controlflow/Cfg.expected +++ b/rust/ql/test/library-tests/controlflow/Cfg.expected @@ -1,4 +1,25 @@ edges +| cfg.rs:1:1:3:1 | enter fn cfg_expr | cfg.rs:2:9:2:14 | CfgPredExpr | | +| cfg.rs:1:1:3:1 | exit fn cfg_expr (normal) | cfg.rs:1:1:3:1 | exit fn cfg_expr | | +| cfg.rs:1:27:3:1 | { ... } | cfg.rs:1:1:3:1 | exit fn cfg_expr (normal) | | +| cfg.rs:2:5:2:14 | MacroExpr | cfg.rs:1:27:3:1 | { ... } | | +| cfg.rs:2:5:2:14 | cfg!... | cfg.rs:2:5:2:14 | MacroExpr | | +| cfg.rs:2:9:2:14 | CfgPredExpr | cfg.rs:2:9:2:14 | { ... } | | +| cfg.rs:2:9:2:14 | { ... } | cfg.rs:2:5:2:14 | cfg!... | | +| cfg.rs:5:1:10:1 | enter fn cfg_pat | cfg.rs:5:16:5:20 | value | | +| cfg.rs:5:1:10:1 | exit fn cfg_pat (normal) | cfg.rs:5:1:10:1 | exit fn cfg_pat | | +| cfg.rs:5:16:5:20 | value | cfg.rs:5:16:5:20 | value | | +| cfg.rs:5:16:5:20 | value | cfg.rs:5:16:5:26 | ...: bool | match | +| cfg.rs:5:16:5:26 | ...: bool | cfg.rs:6:11:6:15 | value | | +| cfg.rs:5:37:10:1 | { ... } | cfg.rs:5:1:10:1 | exit fn cfg_pat (normal) | | +| cfg.rs:6:5:9:5 | match value { ... } | cfg.rs:5:37:10:1 | { ... } | | +| cfg.rs:6:11:6:15 | value | cfg.rs:7:9:7:18 | MacroPat | | +| cfg.rs:7:9:7:18 | MacroPat | cfg.rs:7:13:7:18 | CfgPredPat | match | +| cfg.rs:7:13:7:18 | CfgPredPat | cfg.rs:7:23:7:26 | true | match | +| cfg.rs:7:13:7:18 | CfgPredPat | cfg.rs:8:9:8:9 | _ | no-match | +| cfg.rs:7:23:7:26 | true | cfg.rs:6:5:9:5 | match value { ... } | | +| cfg.rs:8:9:8:9 | _ | cfg.rs:8:14:8:18 | false | match | +| cfg.rs:8:14:8:18 | false | cfg.rs:6:5:9:5 | match value { ... } | | | test.rs:5:5:8:5 | enter fn function_call | test.rs:6:9:6:64 | ExprStmt | | | test.rs:5:5:8:5 | exit fn function_call (normal) | test.rs:5:5:8:5 | exit fn function_call | | | test.rs:5:24:8:5 | { ... } | test.rs:5:5:8:5 | exit fn function_call (normal) | | diff --git a/rust/ql/test/library-tests/controlflow/cfg.rs b/rust/ql/test/library-tests/controlflow/cfg.rs new file mode 100644 index 000000000000..874f75e97b18 --- /dev/null +++ b/rust/ql/test/library-tests/controlflow/cfg.rs @@ -0,0 +1,10 @@ +pub fn cfg_expr() -> bool { + cfg!(unix) +} + +pub fn cfg_pat(value: bool) -> bool { + match value { + cfg!(unix) => true, + _ => false, + } +}