diff --git a/rust/ql/.generated.list b/rust/ql/.generated.list index 92d0a7a4cd84..e3ec533203df 100644 --- a/rust/ql/.generated.list +++ b/rust/ql/.generated.list @@ -144,7 +144,7 @@ lib/codeql/rust/elements/SliceTypeRepr.qll 730e4d0eeefb9b2284e15b41cd0afc3cbe255 lib/codeql/rust/elements/SourceFile.qll 0b6a3e58767c07602b19975009a2ad53ecf1fd721302af543badb643c1fbb6c4 511d5564aab70b1fcd625e07f3d7e3ceb0c4811a5740de64a55a9a728ba8d32c lib/codeql/rust/elements/Static.qll 9dca6d4fb80fb4ead49a3de89bec2b02bae6f96fbc2601dde35a2aa69a9bfdb0 70f67bc75d7799dab04ea7a7fd13286bb76bbe514be16d23149c59dfb31fd0c9 lib/codeql/rust/elements/Stmt.qll 532b12973037301246daf7d8c0177f734202f43d9261c7a4ca6f5080eea8ca64 b838643c4f2b4623d2c816cddad0e68ca3e11f2879ab7beaece46f489ec4b1f3 -lib/codeql/rust/elements/StmtList.qll e874859ce03672d0085e47e0ca5e571b92b539b31bf0d5a8802f9727bef0c6b0 e5fe83237f713cdb57c446a6e1c20f645c2f49d9f5ef2c984032df83acb3c0de +lib/codeql/rust/elements/StmtList.qll 8bad277dfd88735195b8fd43bb1395cb2393c488d89304d6a6e6d8ec3eb24b73 cd1d483aecb8bb1876b8153a872f680febc2ef6c315d661c85ec1b2fa07e4fc0 lib/codeql/rust/elements/Struct.qll 297d3ea732fc7fbb8b8fb5479c1873ce84705146853ff752c84a6f70af12b923 3df0e5fd50a910a0b5611c3a860a1d7c318f6925c3a0727006d91840caf04812 lib/codeql/rust/elements/StructExpr.qll 84f384ef74c723796e514186037a91dd9666556f62c717f133ce22e9dda4425f 176497835252cfdfe110e58ebde9fbde553d03e44e07d3e4d8041e835dbf31b9 lib/codeql/rust/elements/StructExprField.qll 3eb9f17ecd1ad38679689eb4ecc169d3a0b5b7a3fc597ae5a957a7aea2f74e4f 8fcd26f266f203004899a60447ba16e7eae4e3a654fbec7f54e26857730ede93 @@ -385,7 +385,6 @@ lib/codeql/rust/elements/internal/StaticConstructor.qll 6dd7ee3fd16466c407de35b4 lib/codeql/rust/elements/internal/StaticImpl.qll 48071e29c72032b59ad82771d54be92ac0f4c1a68fb1129c5c7991385804d7b1 85c0be8e37a91d6e775b191f0cb52dd8bf70418e6e9947b82c58c40a6d73b406 lib/codeql/rust/elements/internal/StmtImpl.qll ea99d261f32592ff368cc3a1960864989897c92944f1675549e0753964cb562f 9117b4cdfad56f8fa3bc5d921c2146b4ff0658e8914ac51bf48eb3e68599dd6b lib/codeql/rust/elements/internal/StmtListConstructor.qll 435d59019e17a6279110a23d3d5dfbc1d1e16fc358a93a1d688484d22a754866 23fcb60a5cbb66174e459bc10bd7c28ed532fd1ab46f10b9f0c8a6291d3e343f -lib/codeql/rust/elements/internal/StmtListImpl.qll b39f93534013fe38fee68fbc0232146c92b5f90ee0f6e36da31fb1a3797b3175 2b26bc14c2afb94de2d27ba511eca21313b6fc021c827637cd5904154abb9f3f lib/codeql/rust/elements/internal/StructConstructor.qll 52921ea6e70421fd08884dc061d0c2dfbbb8dd83d98f1f3c70572cfe57b2a173 dcb3ea8e45ee875525c645fe5d08e6db9013b86bd351c77df4590d0c1439ab9f lib/codeql/rust/elements/internal/StructExprConstructor.qll 69761fa65a4bedf2893fdfc49753fd1289d9eb64cf405227458161b95fa550cb 72ed5f32dcf6a462d9d3cadfc57395a40ee6f4e294a88dbda78761b4a0759ece lib/codeql/rust/elements/internal/StructExprFieldConstructor.qll 6766d7941963904b3a704e64381a478d410c2ef88e8facbc82efca4e781dac96 a14ce465f0f4e43dea5c21c269d803b0ad452d2eb03f4342ea7a9f5d0b357d60 @@ -585,7 +584,7 @@ lib/codeql/rust/elements/internal/generated/PtrTypeRepr.qll 8d0ea4f6c7f8203340bf lib/codeql/rust/elements/internal/generated/PureSynthConstructors.qll e5b8e69519012bbaae29dcb82d53f7f7ecce368c0358ec27ef6180b228a0057f e5b8e69519012bbaae29dcb82d53f7f7ecce368c0358ec27ef6180b228a0057f lib/codeql/rust/elements/internal/generated/RangeExpr.qll 23cca03bf43535f33b22a38894f70d669787be4e4f5b8fe5c8f7b964d30e9027 18624cef6c6b679eeace2a98737e472432e0ead354cca02192b4d45330f047c9 lib/codeql/rust/elements/internal/generated/RangePat.qll 80826a6a6868a803aa2372e31c52a03e1811a3f1f2abdb469f91ca0bfdd9ecb6 34ee1e208c1690cba505dff2c588837c0cd91e185e2a87d1fe673191962276a9 -lib/codeql/rust/elements/internal/generated/Raw.qll ae8ebdaa26dc2dfbcc8d64c9c7b296de2e0e78086ce7545cbedfa1f560ef2ffa 6a78058f346e34a2da4dd984f76bf848d7d6708d4c0a35151303748cb0ea92fa +lib/codeql/rust/elements/internal/generated/Raw.qll 11d48da73543efe2d6c4c5a30ac8ecdd3c24dc64bbd10bf6976b53445e248ef1 72fddbec1e8e5029442c962599877459406010d81dece075147aa1cc37cf7a42 lib/codeql/rust/elements/internal/generated/RefExpr.qll 7d995884e3dc1c25fc719f5d7253179344d63650e217e9ff6530285fe7a57f64 f2c3c12551deea4964b66553fb9b6423ee16fec53bd63db4796191aa60dc6c66 lib/codeql/rust/elements/internal/generated/RefPat.qll 456ede39837463ee22a630ec7ab6c8630d3664a8ea206fcc6e4f199e92fa564c 5622062765f32930465ba6b170e986706f159f6070f48adee3c20e24e8df4e05 lib/codeql/rust/elements/internal/generated/RefTypeRepr.qll 5b0663a6d234572fb3e467e276d019415caa95ef006438cc59b7af4e1783161e 0e27c8a8f0e323c0e4d6db01fca821bf07c0864d293cdf96fa891b10820c1e4b @@ -600,7 +599,7 @@ lib/codeql/rust/elements/internal/generated/SliceTypeRepr.qll 6f4f9d7e29784ce95d lib/codeql/rust/elements/internal/generated/SourceFile.qll 4bc95c88b49868d1da1a887b35e43ae81e51a69407e79463f5e8824801859380 5641581d70241c0d0d0426976968576ebbef10c183f0371583b243e4e5bbf576 lib/codeql/rust/elements/internal/generated/Static.qll 1a6c87d3c5602e3d02268ebe2463a4ac64614ad25e8966a9bdb9c0ef58991365 cc1fe16d70cdce41a12e41a8f80cc38bdd7efa49c1544e35342fcf3cd26b8219 lib/codeql/rust/elements/internal/generated/Stmt.qll 8473ff532dd5cc9d7decaddcd174b94d610f6ca0aec8e473cc051dad9f3db917 6ef7d2b5237c2dbdcacbf7d8b39109d4dc100229f2b28b5c9e3e4fbf673ba72b -lib/codeql/rust/elements/internal/generated/StmtList.qll 816aebf8f56e179f5f0ba03e80d257ee85459ea757392356a0af6dbd0cd9ef5e 6aa51cdcdc8d93427555fa93f0e84afdfbbd4ffc8b8d378ae4a22b5b6f94f48b +lib/codeql/rust/elements/internal/generated/StmtList.qll 834b87cd93f0c5b41736fb52a6c25fd0e3bdce41d5a64cb3d0810c54e90507f4 ec42f2dfa322044ceaaf90d278f0e7e751d63710facbaf3f5ee69ca3c64ecd06 lib/codeql/rust/elements/internal/generated/Struct.qll 999da1b46e40d6e03fd2338fea02429462877c329c5d1338618cbd886a81567e daa7ff7bd32c554462e0a1502d8319cb5e734e056d0564e06596e416e2b88e9d lib/codeql/rust/elements/internal/generated/StructExpr.qll e77702890561102af38f52d836729e82569c964f8d4c7e680b27992c1ff0f141 23dc51f68107ab0e5c9dd88a6bcc85bb66e8e0f4064cb4d416f50f2ba5db698c lib/codeql/rust/elements/internal/generated/StructExprField.qll 6bdc52ed325fd014495410c619536079b8c404e2247bd2435aa7685dd56c3833 501a30650cf813176ff325a1553da6030f78d14be3f84fea6d38032f4262c6b0 diff --git a/rust/ql/.gitattributes b/rust/ql/.gitattributes index 19f5c2842403..df4a65e7d957 100644 --- a/rust/ql/.gitattributes +++ b/rust/ql/.gitattributes @@ -387,7 +387,6 @@ /lib/codeql/rust/elements/internal/StaticImpl.qll linguist-generated /lib/codeql/rust/elements/internal/StmtImpl.qll linguist-generated /lib/codeql/rust/elements/internal/StmtListConstructor.qll linguist-generated -/lib/codeql/rust/elements/internal/StmtListImpl.qll linguist-generated /lib/codeql/rust/elements/internal/StructConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/StructExprConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/StructExprFieldConstructor.qll linguist-generated diff --git a/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll b/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll index ddc4dae9b958..609a68fc3925 100644 --- a/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll +++ b/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll @@ -266,15 +266,8 @@ module ExprTrees { } } - private AstNode getBlockChildNode(BlockExpr b, int i) { - result = b.getStmtList().getStatement(i) - or - i = b.getStmtList().getNumberOfStatements() and - result = b.getStmtList().getTailExpr() - } - class AsyncBlockExprTree extends StandardTree, PreOrderTree, PostOrderTree, AsyncBlockExpr { - override AstNode getChildNode(int i) { result = getBlockChildNode(this, i) } + override AstNode getChildNode(int i) { result = this.getStmtList().getStmtOrExpr(i) } override predicate propagatesAbnormal(AstNode child) { none() } } @@ -282,7 +275,7 @@ module ExprTrees { class BlockExprTree extends StandardPostOrderTree, BlockExpr { BlockExprTree() { not this.isAsync() } - override AstNode getChildNode(int i) { result = getBlockChildNode(this, i) } + override AstNode getChildNode(int i) { result = this.getStmtList().getStmtOrExpr(i) } override predicate propagatesAbnormal(AstNode child) { child = this.getChildNode(_) } } diff --git a/rust/ql/lib/codeql/rust/elements/StmtList.qll b/rust/ql/lib/codeql/rust/elements/StmtList.qll index 76a4b5d2c34a..9401cb99084c 100644 --- a/rust/ql/lib/codeql/rust/elements/StmtList.qll +++ b/rust/ql/lib/codeql/rust/elements/StmtList.qll @@ -10,13 +10,15 @@ import codeql.rust.elements.Expr import codeql.rust.elements.Stmt /** - * A list of statements in a block. + * A list of statements in a block, with an optional tail expression at the + * end that determines the block's value. * * For example: * ```rust * { * let x = 1; * let y = 2; + * x + y * } * // ^^^^^^^^^ * ``` diff --git a/rust/ql/lib/codeql/rust/elements/internal/StmtListImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/StmtListImpl.qll index 85940ef7d21c..d56b4c49ce21 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/StmtListImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/StmtListImpl.qll @@ -1,4 +1,3 @@ -// generated by codegen, remove this comment if you wish to edit this file /** * This module provides a hand-modifiable wrapper around the generated class `StmtList`. * @@ -12,17 +11,48 @@ private import codeql.rust.elements.internal.generated.StmtList * be referenced directly. */ module Impl { + // the following QLdoc is generated: if you need to edit it, do it in the schema file /** - * A list of statements in a block. + * A list of statements in a block, with an optional tail expression at the + * end that determines the block's value. * * For example: * ```rust * { * let x = 1; * let y = 2; + * x + y * } * // ^^^^^^^^^ * ``` */ - class StmtList extends Generated::StmtList { } + class StmtList extends Generated::StmtList { + /** + * Gets the `index`th statement or expression of this statement list (0-based). + * + * This includes both the statements and any tail expression in the statement list. To access + * just the statements, use `getStatement`. To access just the tail expression, if any, + * use `getTailExpr`. + */ + AstNode getStmtOrExpr(int index) { + result = this.getStatement(index) + or + index = this.getNumberOfStatements() and + result = this.getTailExpr() + } + + /** + * Gets any of the statements or expressions of this statement list. + * + * This includes both the statements and any tail expression in the statement list. To access + * just the statements, use `getAStatement`. To access just the tail expression, if any, + * use `getTailExpr`. + */ + final AstNode getAStmtOrExpr() { result = this.getStmtOrExpr(_) } + + /** + * Gets the number of statements or expressions of this statement list. + */ + final int getNumberOfStmtOrExpr() { result = count(int i | exists(this.getStmtOrExpr(i))) } + } } 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 abf844b77f5a..de56bdffb6c1 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/generated/Raw.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/generated/Raw.qll @@ -943,13 +943,15 @@ module Raw { /** * INTERNAL: Do not use. - * A list of statements in a block. + * A list of statements in a block, with an optional tail expression at the + * end that determines the block's value. * * For example: * ```rust * { * let x = 1; * let y = 2; + * x + y * } * // ^^^^^^^^^ * ``` @@ -964,11 +966,17 @@ module Raw { /** * Gets the `index`th statement of this statement list (0-based). + * + * The statements of a `StmtList` do not include any tail expression, which + * can be accessed with predicates such as `getTailExpr`. */ Stmt getStatement(int index) { stmt_list_statements(this, index, result) } /** * Gets the tail expression of this statement list, if it exists. + * + * The tail expression is the expression at the end of a block, that + * determines the block's value. */ Expr getTailExpr() { stmt_list_tail_exprs(this, result) } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/generated/StmtList.qll b/rust/ql/lib/codeql/rust/elements/internal/generated/StmtList.qll index 3460c239a9f3..26a7f1f363a4 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/generated/StmtList.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/generated/StmtList.qll @@ -17,13 +17,15 @@ import codeql.rust.elements.Stmt */ module Generated { /** - * A list of statements in a block. + * A list of statements in a block, with an optional tail expression at the + * end that determines the block's value. * * For example: * ```rust * { * let x = 1; * let y = 2; + * x + y * } * // ^^^^^^^^^ * ``` @@ -53,6 +55,9 @@ module Generated { /** * Gets the `index`th statement of this statement list (0-based). + * + * The statements of a `StmtList` do not include any tail expression, which + * can be accessed with predicates such as `getTailExpr`. */ Stmt getStatement(int index) { result = @@ -73,6 +78,9 @@ module Generated { /** * Gets the tail expression of this statement list, if it exists. + * + * The tail expression is the expression at the end of a block, that + * determines the block's value. */ Expr getTailExpr() { result = diff --git a/rust/ql/test/extractor-tests/generated/.generated_tests.list b/rust/ql/test/extractor-tests/generated/.generated_tests.list index c0e2d095be66..2fcb0b79be47 100644 --- a/rust/ql/test/extractor-tests/generated/.generated_tests.list +++ b/rust/ql/test/extractor-tests/generated/.generated_tests.list @@ -114,7 +114,7 @@ SlicePat/gen_slice_pat.rs df4a6692f5100aa11dd777561400ce71e37b85f2363b0638c21975 SliceTypeRepr/gen_slice_type_repr.rs 4a85402d40028c5a40ef35018453a89700b2171bc62fd86587378484831b969f 4a85402d40028c5a40ef35018453a89700b2171bc62fd86587378484831b969f SourceFile/gen_source_file.rs c0469cc8f0ecce3dd2e77963216d7e8808046014533359a44c1698e48783b420 c0469cc8f0ecce3dd2e77963216d7e8808046014533359a44c1698e48783b420 Static/gen_static.rs 21314018ea184c1ddcb594d67bab97ae18ceaf663d9f120f39ff755d389dde7a 21314018ea184c1ddcb594d67bab97ae18ceaf663d9f120f39ff755d389dde7a -StmtList/gen_stmt_list.rs adbd82045a50e2051434ce3cdd524c9f2c6ad9f3dd02b4766fb107e2e99212db adbd82045a50e2051434ce3cdd524c9f2c6ad9f3dd02b4766fb107e2e99212db +StmtList/gen_stmt_list.rs 1051a20a90b59142e3fddfbbabd0eff586586b1812c6ab788c5391153bab8851 1051a20a90b59142e3fddfbbabd0eff586586b1812c6ab788c5391153bab8851 Struct/gen_struct.rs 5e181e90075f716c04c75e4ef0334abe3d5f419cd9ccfadfe595c09fab33566b 5e181e90075f716c04c75e4ef0334abe3d5f419cd9ccfadfe595c09fab33566b StructExpr/gen_struct_expr.rs e7824008b0b73d02f6243fd8a18e0ef93c63bfe775a878fc2679c3870fc342fd e7824008b0b73d02f6243fd8a18e0ef93c63bfe775a878fc2679c3870fc342fd StructExprField/gen_struct_expr_field.rs 4ccca8e8ad462b4873f5604f0afdd1836027b8d39e36fbe7d6624ef3e744a084 4ccca8e8ad462b4873f5604f0afdd1836027b8d39e36fbe7d6624ef3e744a084 diff --git a/rust/ql/test/extractor-tests/generated/StmtList/StmtList.expected b/rust/ql/test/extractor-tests/generated/StmtList/StmtList.expected index 02f322734ca6..5c5d77a34ed4 100644 --- a/rust/ql/test/extractor-tests/generated/StmtList/StmtList.expected +++ b/rust/ql/test/extractor-tests/generated/StmtList/StmtList.expected @@ -1,9 +1,10 @@ instances -| gen_stmt_list.rs:3:27:12:1 | StmtList | -| gen_stmt_list.rs:7:5:10:5 | StmtList | +| gen_stmt_list.rs:3:27:14:1 | StmtList | +| gen_stmt_list.rs:8:5:12:5 | StmtList | getAttr getStatement -| gen_stmt_list.rs:7:5:10:5 | StmtList | 0 | gen_stmt_list.rs:8:9:8:18 | let ... = 1 | -| gen_stmt_list.rs:7:5:10:5 | StmtList | 1 | gen_stmt_list.rs:9:9:9:18 | let ... = 2 | +| gen_stmt_list.rs:8:5:12:5 | StmtList | 0 | gen_stmt_list.rs:9:9:9:18 | let ... = 1 | +| gen_stmt_list.rs:8:5:12:5 | StmtList | 1 | gen_stmt_list.rs:10:9:10:18 | let ... = 2 | getTailExpr -| gen_stmt_list.rs:3:27:12:1 | StmtList | gen_stmt_list.rs:7:5:10:5 | { ... } | +| gen_stmt_list.rs:3:27:14:1 | StmtList | gen_stmt_list.rs:8:5:12:5 | { ... } | +| gen_stmt_list.rs:8:5:12:5 | StmtList | gen_stmt_list.rs:11:9:11:13 | ... + ... | diff --git a/rust/ql/test/extractor-tests/generated/StmtList/gen_stmt_list.rs b/rust/ql/test/extractor-tests/generated/StmtList/gen_stmt_list.rs index 8cc83732b62f..9802e4bc9950 100644 --- a/rust/ql/test/extractor-tests/generated/StmtList/gen_stmt_list.rs +++ b/rust/ql/test/extractor-tests/generated/StmtList/gen_stmt_list.rs @@ -1,12 +1,14 @@ // generated by codegen, do not edit fn test_stmt_list() -> () { - // A list of statements in a block. + // A list of statements in a block, with an optional tail expression at the + // end that determines the block's value. // // For example: { let x = 1; let y = 2; + x + y } // ^^^^^^^^^ } diff --git a/rust/ql/test/library-tests/operations/Cargo.lock b/rust/ql/test/library-tests/elements/operations/Cargo.lock similarity index 100% rename from rust/ql/test/library-tests/operations/Cargo.lock rename to rust/ql/test/library-tests/elements/operations/Cargo.lock diff --git a/rust/ql/test/library-tests/operations/Operations.expected b/rust/ql/test/library-tests/elements/operations/Operations.expected similarity index 100% rename from rust/ql/test/library-tests/operations/Operations.expected rename to rust/ql/test/library-tests/elements/operations/Operations.expected diff --git a/rust/ql/test/library-tests/operations/Operations.ql b/rust/ql/test/library-tests/elements/operations/Operations.ql similarity index 100% rename from rust/ql/test/library-tests/operations/Operations.ql rename to rust/ql/test/library-tests/elements/operations/Operations.ql diff --git a/rust/ql/test/library-tests/operations/test.rs b/rust/ql/test/library-tests/elements/operations/test.rs similarity index 100% rename from rust/ql/test/library-tests/operations/test.rs rename to rust/ql/test/library-tests/elements/operations/test.rs diff --git a/rust/ql/test/library-tests/elements/stmtlist/Cargo.lock b/rust/ql/test/library-tests/elements/stmtlist/Cargo.lock new file mode 100644 index 000000000000..b9856cfaf77d --- /dev/null +++ b/rust/ql/test/library-tests/elements/stmtlist/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "test" +version = "0.0.1" diff --git a/rust/ql/test/library-tests/elements/stmtlist/StmtList.expected b/rust/ql/test/library-tests/elements/stmtlist/StmtList.expected new file mode 100644 index 000000000000..820b1a76dc93 --- /dev/null +++ b/rust/ql/test/library-tests/elements/stmtlist/StmtList.expected @@ -0,0 +1,9 @@ +| StmtList.rs:4:19:9:1 | StmtList | 2 | hasTailExpr | 0:let ... = 1, 1:let ... = 2, 2:... + ... | +| StmtList.rs:11:18:15:1 | StmtList | 2 | | 0:let ... = 1, 1:let ... = 2 | +| StmtList.rs:17:19:20:1 | StmtList | 0 | hasTailExpr | 0:... + ... | +| StmtList.rs:22:18:25:1 | StmtList | 1 | | 0:ExprStmt | +| StmtList.rs:27:18:29:1 | StmtList | 0 | | | +| StmtList.rs:31:18:34:1 | StmtList | 0 | | | +| StmtList.rs:36:29:43:1 | StmtList | 0 | hasTailExpr | 0:if cond {...} else {...} | +| StmtList.rs:38:10:40:2 | StmtList | 0 | hasTailExpr | 0:1 | +| StmtList.rs:40:9:42:2 | StmtList | 0 | hasTailExpr | 0:2 | diff --git a/rust/ql/test/library-tests/elements/stmtlist/StmtList.ql b/rust/ql/test/library-tests/elements/stmtlist/StmtList.ql new file mode 100644 index 000000000000..048dcd06d6ea --- /dev/null +++ b/rust/ql/test/library-tests/elements/stmtlist/StmtList.ql @@ -0,0 +1,13 @@ +import rust +import TestUtils + +from StmtList sl, string tail +where + toBeTested(sl) and + if sl.hasTailExpr() then tail = "hasTailExpr" else tail = "" +select sl, sl.getNumberOfStatements(), tail, + concat(int i, AstNode n | + n = sl.getStmtOrExpr(i) + | + i.toString() + ":" + n.toString(), ", " order by i + ) diff --git a/rust/ql/test/library-tests/elements/stmtlist/StmtList.rs b/rust/ql/test/library-tests/elements/stmtlist/StmtList.rs new file mode 100644 index 000000000000..1437f2afb263 --- /dev/null +++ b/rust/ql/test/library-tests/elements/stmtlist/StmtList.rs @@ -0,0 +1,43 @@ + +// --- tests --- + +fn test1() -> i32 { + // two statements + tail expression + let a = 1; + let b = 2; + a + b +} + +fn test2() -> () { + // two statements only + let a = 1; + let b = 2; +} + +fn test3() -> i32 { + // tail expression only + 1 + 2 +} + +fn test4() -> () { + // one statement only + 1 + 2; +} + +fn test5() -> () { + // neither +} + +fn test6() -> () { + // neither + ; +} + +fn test7(cond: bool) -> i32 { + // nested blocks + if cond { + 1 + } else { + 2 + } +} diff --git a/rust/schema/annotations.py b/rust/schema/annotations.py index 371493926756..ce1b97570ee6 100644 --- a/rust/schema/annotations.py +++ b/rust/schema/annotations.py @@ -1828,18 +1828,27 @@ class _: @annotate(StmtList) class _: """ - A list of statements in a block. + A list of statements in a block, with an optional tail expression at the + end that determines the block's value. For example: ```rust { let x = 1; let y = 2; + x + y } // ^^^^^^^^^ ``` """ - + statements: _ | doc("statements of this statement list") | desc(""" + The statements of a `StmtList` do not include any tail expression, which + can be accessed with predicates such as `getTailExpr`. + """) + tail_expr: _ | doc("tail expression of this statement list") | desc(""" + The tail expression is the expression at the end of a block, that + determines the block's value. + """) @annotate(Struct, replace_bases={Item: None}) # still an Item via Adt class _: