diff --git a/rust/ql/.generated.list b/rust/ql/.generated.list index eb997e2eeffc..18337b8a6d78 100644 --- a/rust/ql/.generated.list +++ b/rust/ql/.generated.list @@ -193,7 +193,6 @@ lib/codeql/rust/elements/internal/ClosureBinderImpl.qll 58c6b17d34d678802ce3484f lib/codeql/rust/elements/internal/ClosureExprConstructor.qll a348229d2b25c7ebd43b58461830b7915e92d31ae83436ec831e0c4873f6218a 70a1d2ac33db3ac4da5826b0e8628f2f29a8f9cdfd8e4fd0e488d90ce0031a38 lib/codeql/rust/elements/internal/ClosureExprImpl.qll 5ae3d211273b3effc3bff9f06bcef480f8264084e0509e69b8ff29bc29f47b05 ff562bc8d15ecb76ada3111c7c74dd990a0e80f41a32477f5f2f7db9e8f71102 lib/codeql/rust/elements/internal/CommentConstructor.qll 0b4a6a976d667bf7595500dfb91b9cfc87460a501837ba5382d9a8d8321d7736 7d02d8c94a319dc48e7978d5270e33fc5c308d443768ff96b618236d250123f1 -lib/codeql/rust/elements/internal/CommentImpl.qll c1b7f2fca9cfb7e611b25486ca5f06c4996f4436b72ed3a76e27a6409af4ec01 36f7d7c6d2dadda4d3423afc4f23bdaf275978b6f3d9ca71bf145afc92858f9c lib/codeql/rust/elements/internal/ConstArgConstructor.qll f63021dc1ca2276786da3a981d06c18d7a360b5e75c08bca5d1afece4f7c4a83 487a870cbf5ed6554d671a8e159edd9261d853eba2d28ce2bd459759f47f11f2 lib/codeql/rust/elements/internal/ConstArgImpl.qll 234fe6533c208a1731cdb423aa3a28909bd7e042dbc28bbedfd4f62e42b6f21e c576a49006f7a10483041fc07f2f0d089710ac61840be61a2e71140db709f9c6 lib/codeql/rust/elements/internal/ConstBlockPatConstructor.qll ddb4a0045635d477e87360ecafec0ba90ddcffc6e62996eb6e7edd5a5d65b860 442061d0497a615b3f008b990f5e3c4f045110f76500eff81a7f44ffd1319acf @@ -239,7 +238,6 @@ lib/codeql/rust/elements/internal/GenericParamImpl.qll f435f80d7f275803c1311d362 lib/codeql/rust/elements/internal/GenericParamListConstructor.qll 7221146d1724e0add3a8e70e0e46670142589eb7143425e1871ac4358a8c8bdb 2fbb7576444d6b2da6164245e2660d592d276ae2c1ca9f2bda5656b1c5c0a73a lib/codeql/rust/elements/internal/GenericParamListImpl.qll 524aa0949df6d4d2cb9bee6226650f63a6f181d7644933fa265673b281074885 27b0210e5eaa2040bc8a093e35e1394befb6994b25369544738d0447ef269a9c lib/codeql/rust/elements/internal/IdentPatConstructor.qll 09792f5a070996b65f095dc6b1b9e0fb096a56648eed26c0643c59f82377cab0 0bb1a9fcdc62b5197aef3dd6e0ea4d679dde10d5be54b57b5209727ba66e078b -lib/codeql/rust/elements/internal/IdentPatImpl.qll 10b2758419b48d34013d0e1ea55006a72ea351e5298c9cde4d988f510d4094eb 63bdb210d7bcab42888b4f44688966a33951061573b0a9a734b5b262cbfa2cd8 lib/codeql/rust/elements/internal/IfExprConstructor.qll 03088b54c8fa623f93a5b5a7eb896f680e8b0e9025488157a02c48aaebc6ad56 906f916c3690d0721a31dd31b302dcdcec4233bb507683007d82cf10793a648f lib/codeql/rust/elements/internal/IfExprImpl.qll 96dc5be0a650a74f96e0c2214eb58f1af5278ad1695ad790b660fdecb6738c14 06a292fcc459297ef3a0ef5c75c887f993ccd6350eb3fb0d2493e5b7c7199b6b lib/codeql/rust/elements/internal/ImplConstructor.qll 24edccca59f70d812d1458b412a45310ddc096d095332f6e3258903c54c1bb44 7eb673b3ab33a0873ee5ce189105425066b376821cce0fc9eb8ace22995f0bc7 diff --git a/rust/ql/.gitattributes b/rust/ql/.gitattributes index b3526b1ec22f..8e15852654c4 100644 --- a/rust/ql/.gitattributes +++ b/rust/ql/.gitattributes @@ -195,7 +195,6 @@ /lib/codeql/rust/elements/internal/ClosureExprConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/ClosureExprImpl.qll linguist-generated /lib/codeql/rust/elements/internal/CommentConstructor.qll linguist-generated -/lib/codeql/rust/elements/internal/CommentImpl.qll linguist-generated /lib/codeql/rust/elements/internal/ConstArgConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/ConstArgImpl.qll linguist-generated /lib/codeql/rust/elements/internal/ConstBlockPatConstructor.qll linguist-generated @@ -241,7 +240,6 @@ /lib/codeql/rust/elements/internal/GenericParamListConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/GenericParamListImpl.qll linguist-generated /lib/codeql/rust/elements/internal/IdentPatConstructor.qll linguist-generated -/lib/codeql/rust/elements/internal/IdentPatImpl.qll linguist-generated /lib/codeql/rust/elements/internal/IfExprConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/IfExprImpl.qll linguist-generated /lib/codeql/rust/elements/internal/ImplConstructor.qll linguist-generated diff --git a/rust/ql/lib/codeql/rust/elements/Variable.qll b/rust/ql/lib/codeql/rust/elements/Variable.qll new file mode 100644 index 000000000000..76c2d9f19f72 --- /dev/null +++ b/rust/ql/lib/codeql/rust/elements/Variable.qll @@ -0,0 +1,9 @@ +/** + * This module provides classes related to variables. + */ + +private import internal.VariableImpl + +final class Variable = Impl::Variable; + +final class VariableAccess = Impl::VariableAccess; diff --git a/rust/ql/lib/codeql/rust/elements/internal/CommentImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/CommentImpl.qll index 0e5b68b0f358..32a4f415ab7c 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/CommentImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/CommentImpl.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 `Comment`. * @@ -12,6 +11,7 @@ private import codeql.rust.elements.internal.generated.Comment * be referenced directly. */ module Impl { + // the following QLdoc is generated: if you need to edit it, do it in the schema file /** * A comment. For example: * ```rust @@ -19,5 +19,12 @@ module Impl { * /// This is a doc comment * ``` */ - class Comment extends Generated::Comment { } + class Comment extends Generated::Comment { + /** + * Gets the text of this comment, excluding the comment marker. + */ + string getCommentText() { + exists(string s | s = this.getText() | result = s.regexpCapture("///?\\s*(.*)", 1)) + } + } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/IdentPatImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/IdentPatImpl.qll index 6f90f3d6d032..0c6092074774 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/IdentPatImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/IdentPatImpl.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 `IdentPat`. * @@ -12,6 +11,7 @@ private import codeql.rust.elements.internal.generated.IdentPat * be referenced directly. */ module Impl { + // the following QLdoc is generated: if you need to edit it, do it in the schema file /** * A binding pattern. For example: * ```rust @@ -27,5 +27,7 @@ module Impl { * }; * ``` */ - class IdentPat extends Generated::IdentPat { } + class IdentPat extends Generated::IdentPat { + override string toString() { result = this.getName().getText() } + } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll new file mode 100644 index 000000000000..58c9a4fb6ebf --- /dev/null +++ b/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll @@ -0,0 +1,387 @@ +private import rust +private import codeql.rust.elements.internal.generated.ParentChild +private import codeql.rust.elements.internal.PathExprImpl::Impl as PathExprImpl + +module Impl { + /** + * A variable scope. Either a block `{ ... }`, the guard/rhs + * of a match arm, or the body of a closure. + */ + abstract class VariableScope extends AstNode { } + + class BlockExprScope extends VariableScope, BlockExpr { } + + abstract class MatchArmScope extends VariableScope { + MatchArm arm; + + bindingset[arm] + MatchArmScope() { exists(arm) } + + Pat getPat() { result = arm.getPat() } + } + + class MatchArmExprScope extends MatchArmScope { + MatchArmExprScope() { this = arm.getExpr() } + } + + class MatchArmGuardScope extends MatchArmScope { + MatchArmGuardScope() { this = arm.getGuard() } + } + + class ClosureBodyScope extends VariableScope { + ClosureBodyScope() { this = any(ClosureExpr ce).getBody() } + } + + private Pat getImmediatePatParent(AstNode n) { + result = getImmediateParent(n) + or + result.(RecordPat).getRecordPatFieldList().getAField().getPat() = n + } + + private Pat getAPatAncestor(Pat p) { + (p instanceof IdentPat or p instanceof OrPat) and + exists(Pat p0 | result = getImmediatePatParent(p0) | + p0 = p + or + p0 = getAPatAncestor(p) and + not p0 instanceof OrPat + ) + } + + /** Gets the immediately enclosing `|` pattern of `p`, if any */ + private OrPat getEnclosingOrPat(Pat p) { result = getAPatAncestor(p) } + + /** Gets the outermost enclosing `|` pattern parent of `p`, if any. */ + private OrPat getOutermostEnclosingOrPat(IdentPat p) { + result = getEnclosingOrPat+(p) and + not exists(getEnclosingOrPat(result)) + } + + /** + * Holds if `p` declares a variable named `name` at `definingNode`. Normally, + * `definingNode = p`, except in cases like + * + * ```rust + * match either { + * Either::Left(x) | Either::Right(x) => println!(x), + * } + * ``` + * + * where `definingNode` is the entire `Either::Left(x) | Either::Right(x)` + * pattern. + */ + private predicate variableDecl(AstNode definingNode, IdentPat p, string name) { + ( + definingNode = getOutermostEnclosingOrPat(p) + or + not exists(getOutermostEnclosingOrPat(p)) and + definingNode = p.getName() + ) and + name = p.getName().getText() + } + + /** A variable. */ + class Variable extends MkVariable { + private AstNode definingNode; + private string name; + + Variable() { this = MkVariable(definingNode, name) } + + /** Gets the name of this variable. */ + string getName() { result = name } + + /** Gets the location of this variable. */ + Location getLocation() { result = definingNode.getLocation() } + + /** Gets a textual representation of this variable. */ + string toString() { result = this.getName() } + + /** Gets an access to this variable. */ + VariableAccess getAnAccess() { result.getVariable() = this } + } + + /** A path expression that may access a local variable. */ + private class VariableAccessCand extends PathExpr { + string name_; + + VariableAccessCand() { + exists(Path p, PathSegment ps | + p = this.getPath() and + not p.hasQualifier() and + ps = p.getPart() and + not ps.hasGenericArgList() and + not ps.hasParamList() and + not ps.hasPathType() and + not ps.hasReturnTypeSyntax() and + name_ = ps.getNameRef().getText() + ) + } + + string getName() { result = name_ } + } + + private AstNode getAnAncestorInVariableScope(AstNode n) { + ( + n instanceof Pat or + n instanceof VariableAccessCand or + n instanceof LetStmt or + n instanceof VariableScope + ) and + exists(AstNode n0 | result = getImmediateParent(n0) | + n0 = n + or + n0 = getAnAncestorInVariableScope(n) and + not n0 instanceof VariableScope + ) + } + + /** Gets the immediately enclosing variable scope of `n`. */ + private VariableScope getEnclosingScope(AstNode n) { result = getAnAncestorInVariableScope(n) } + + private Pat getAVariablePatAncestor(Variable v) { + exists(AstNode definingNode, string name | + v = MkVariable(definingNode, name) and + variableDecl(definingNode, result, name) + ) + or + exists(Pat mid | + mid = getAVariablePatAncestor(v) and + result = getImmediatePatParent(mid) + ) + } + + /** + * Holds if `v` is named `name` and is declared inside variable scope + * `scope`, and `v` is bound starting from `(line, column)`. + */ + private predicate variableDeclInScope( + Variable v, VariableScope scope, string name, int line, int column + ) { + name = v.getName() and + exists(Pat pat | pat = getAVariablePatAncestor(v) | + scope = + any(MatchArmScope arm | + arm.getPat() = pat and + arm.getLocation().hasLocationInfo(_, line, column, _, _) + ) + or + exists(Function f | + f.getParamList().getAParam().getPat() = pat and + scope = f.getBody() and + scope.getLocation().hasLocationInfo(_, line, column, _, _) + ) + or + exists(LetStmt let | + let.getPat() = pat and + scope = getEnclosingScope(let) and + // for `let` statements, variables are bound _after_ the statement, i.e. + // not in the RHS + let.getLocation().hasLocationInfo(_, _, _, line, column) + ) + or + exists(IfExpr ie, LetExpr let | + let.getPat() = pat and + ie.getCondition() = let and + scope = ie.getThen() and + scope.getLocation().hasLocationInfo(_, line, column, _, _) + ) + or + exists(ForExpr fe | + fe.getPat() = pat and + scope = fe.getLoopBody() and + scope.getLocation().hasLocationInfo(_, line, column, _, _) + ) + or + exists(ClosureExpr ce | + ce.getParamList().getAParam().getPat() = pat and + scope = ce.getBody() and + scope.getLocation().hasLocationInfo(_, line, column, _, _) + ) + ) + } + + /** + * Holds if `cand` may access a variable named `name` at + * `(startline, startcolumn, endline, endcolumn)` in the variable scope + * `scope`. + * + * `nestLevel` is the number of nested scopes that need to be traversed + * to reach `scope` from `cand`. + */ + private predicate variableAccessCandInScope( + VariableAccessCand cand, VariableScope scope, string name, int nestLevel, int startline, + int startcolumn, int endline, int endcolumn + ) { + name = cand.getName() and + scope = [cand.(VariableScope), getEnclosingScope(cand)] and + cand.getLocation().hasLocationInfo(_, startline, startcolumn, endline, endcolumn) and + nestLevel = 0 + or + exists(VariableScope inner | + variableAccessCandInScope(cand, inner, name, nestLevel - 1, _, _, _, _) and + scope = getEnclosingScope(inner) and + // Use the location of the inner scope as the location of the access, instead of the + // actual access location. This allows us to collapse multiple accesses in inner + // scopes to a single entity + scope.getLocation().hasLocationInfo(_, startline, startcolumn, endline, endcolumn) + ) + } + + private newtype TVariableOrAccessCand = + TVariableOrAccessCandVariable(Variable v) or + TVariableOrAccessCandVariableAccessCand(VariableAccessCand va) + + /** + * A variable declaration or variable access candidate. + * + * In order to determine whether a candidate is an actual variable access, + * we rank declarations and candidates by their position in source code. + * + * The ranking must take variable names into account, but also variable scopes; + * below a comment `rank(scope, name, i)` means that the declaration/access on + * the given line has rank `i` amongst all declarations/accesses inside variable + * scope `scope`, for variable name `name`: + * + * ```rust + * fn f() { // scope0 + * let x = 0; // rank(scope0, "x", 0) + * use(x); // rank(scope0, "x", 1) + * let x = // rank(scope0, "x", 3) + * x + 1; // rank(scope0, "x", 2) + * let y = // rank(scope0, "y", 0) + * x; // rank(scope0, "x", 4) + * + * { // scope1 + * use(x); // rank(scope1, "x", 0), rank(scope0, "x", 4) + * use(y); // rank(scope1, "y", 0), rank(scope0, "y", 1) + * let x = 2; // rank(scope1, "x", 1) + * use(x); // rank(scope1, "x", 2), rank(scope0, "x", 4) + * } + * } + * ``` + * + * Variable declarations are only ranked in the scope that they bind into, while + * accesses candidates propagate outwards through scopes, as they may access + * declarations from outer scopes. + * + * For an access candidate with ranks `{ rank(scope_i, name, rnk_i) | i in I }` and + * declarations `d in D` with ranks `rnk(scope_d, name, rnk_d)`, the target is + * calculated as + * ``` + * max_{i in I} ( + * max_{d in D | scope_d = scope_i and rnk_d < rnk_i} ( + * d + * ) + * ) + * ``` + * + * i.e., its the nearest declaration before the access in the same (or outer) scope + * as the access. + */ + private class VariableOrAccessCand extends TVariableOrAccessCand { + Variable asVariable() { this = TVariableOrAccessCandVariable(result) } + + VariableAccessCand asVariableAccessCand() { + this = TVariableOrAccessCandVariableAccessCand(result) + } + + string toString() { + result = this.asVariable().toString() or result = this.asVariableAccessCand().toString() + } + + Location getLocation() { + result = this.asVariable().getLocation() or result = this.asVariableAccessCand().getLocation() + } + + pragma[nomagic] + predicate rankBy( + string name, VariableScope scope, int startline, int startcolumn, int endline, int endcolumn + ) { + variableDeclInScope(this.asVariable(), scope, name, startline, startcolumn) and + endline = -1 and + endcolumn = -1 + or + variableAccessCandInScope(this.asVariableAccessCand(), scope, name, _, startline, startcolumn, + endline, endcolumn) + } + } + + /** + * Gets the rank of `v` amongst all other declarations or access candidates + * to a variable named `name` in the variable scope `scope`. + */ + private int rankVariableOrAccess(VariableScope scope, string name, VariableOrAccessCand v) { + v = + rank[result + 1](VariableOrAccessCand v0, int startline, int startcolumn, int endline, + int endcolumn | + v0.rankBy(name, scope, startline, startcolumn, endline, endcolumn) + | + v0 order by startline, startcolumn, endline, endcolumn + ) + } + + /** + * Holds if `v` can reach rank `rnk` in the variable scope `scope`. This is needed to + * take shadowing into account, for example in + * + * ```rust + * let x = 0; // rank 0 + * use(x); // rank 1 + * let x = ""; // rank 2 + * use(x); // rank 3 + * ``` + * + * the declaration at rank 0 can only reach the access at rank 1, while the declaration + * at rank 2 can only reach the access at rank 3. + */ + private predicate variableReachesRank(VariableScope scope, string name, Variable v, int rnk) { + rnk = rankVariableOrAccess(scope, name, TVariableOrAccessCandVariable(v)) + or + variableReachesRank(scope, name, v, rnk - 1) and + rnk = rankVariableOrAccess(scope, name, TVariableOrAccessCandVariableAccessCand(_)) + } + + private predicate variableReachesCand( + VariableScope scope, string name, Variable v, VariableAccessCand cand, int nestLevel + ) { + exists(int rnk | + variableReachesRank(scope, name, v, rnk) and + rnk = rankVariableOrAccess(scope, name, TVariableOrAccessCandVariableAccessCand(cand)) and + variableAccessCandInScope(cand, scope, name, nestLevel, _, _, _, _) + ) + } + + /** A variable access. */ + class VariableAccess extends PathExprImpl::PathExpr instanceof VariableAccessCand { + private string name; + private Variable v; + + VariableAccess() { variableAccess(_, name, v, this) } + + /** Gets the variable being accessed. */ + Variable getVariable() { result = v } + + override string toString() { result = name } + + override string getAPrimaryQlClass() { result = "VariableAccess" } + } + + cached + private module Cached { + cached + newtype TVariable = + MkVariable(AstNode definingNode, string name) { variableDecl(definingNode, _, name) } + + cached + predicate variableAccess(VariableScope scope, string name, Variable v, VariableAccessCand cand) { + v = + min(Variable v0, int nestLevel | + variableReachesCand(scope, name, v0, cand, nestLevel) + | + v0 order by nestLevel + ) + } + } + + private import Cached +} diff --git a/rust/ql/lib/rust.qll b/rust/ql/lib/rust.qll index 72d2bd5498d2..7723400c41b6 100644 --- a/rust/ql/lib/rust.qll +++ b/rust/ql/lib/rust.qll @@ -4,3 +4,4 @@ import codeql.rust.elements import codeql.Locations import codeql.files.FileSystem import codeql.rust.elements.LogicalOperation +import codeql.rust.elements.Variable diff --git a/rust/ql/test/extractor-tests/generated/IdentPat/IdentPat.expected b/rust/ql/test/extractor-tests/generated/IdentPat/IdentPat.expected index 53a4c59d3986..5f7d899ccab9 100644 --- a/rust/ql/test/extractor-tests/generated/IdentPat/IdentPat.expected +++ b/rust/ql/test/extractor-tests/generated/IdentPat/IdentPat.expected @@ -1,2 +1,2 @@ -| gen_ident_pat.rs:6:22:6:22 | IdentPat | getNumberOfAttrs: | 0 | hasName: | yes | hasPat: | no | -| gen_ident_pat.rs:10:9:10:25 | IdentPat | getNumberOfAttrs: | 0 | hasName: | yes | hasPat: | yes | +| gen_ident_pat.rs:6:22:6:22 | y | getNumberOfAttrs: | 0 | hasName: | yes | hasPat: | no | +| gen_ident_pat.rs:10:9:10:25 | y | getNumberOfAttrs: | 0 | hasName: | yes | hasPat: | yes | diff --git a/rust/ql/test/extractor-tests/generated/IdentPat/IdentPat_getName.expected b/rust/ql/test/extractor-tests/generated/IdentPat/IdentPat_getName.expected index 2a49521ead99..45273e9c8a41 100644 --- a/rust/ql/test/extractor-tests/generated/IdentPat/IdentPat_getName.expected +++ b/rust/ql/test/extractor-tests/generated/IdentPat/IdentPat_getName.expected @@ -1,2 +1,2 @@ -| gen_ident_pat.rs:6:22:6:22 | IdentPat | gen_ident_pat.rs:6:22:6:22 | Name | -| gen_ident_pat.rs:10:9:10:25 | IdentPat | gen_ident_pat.rs:10:9:10:9 | Name | +| gen_ident_pat.rs:6:22:6:22 | y | gen_ident_pat.rs:6:22:6:22 | Name | +| gen_ident_pat.rs:10:9:10:25 | y | gen_ident_pat.rs:10:9:10:9 | Name | diff --git a/rust/ql/test/extractor-tests/generated/IdentPat/IdentPat_getPat.expected b/rust/ql/test/extractor-tests/generated/IdentPat/IdentPat_getPat.expected index 705456753b9c..2e2f0d9228e0 100644 --- a/rust/ql/test/extractor-tests/generated/IdentPat/IdentPat_getPat.expected +++ b/rust/ql/test/extractor-tests/generated/IdentPat/IdentPat_getPat.expected @@ -1 +1 @@ -| gen_ident_pat.rs:10:9:10:25 | IdentPat | gen_ident_pat.rs:10:11:10:25 | TupleStructPat | +| gen_ident_pat.rs:10:9:10:25 | y | gen_ident_pat.rs:10:11:10:25 | TupleStructPat | diff --git a/rust/ql/test/extractor-tests/generated/LetExpr/LetExpr_getExpr.expected b/rust/ql/test/extractor-tests/generated/LetExpr/LetExpr_getExpr.expected index 66fab8ec8099..f90fa5862299 100644 --- a/rust/ql/test/extractor-tests/generated/LetExpr/LetExpr_getExpr.expected +++ b/rust/ql/test/extractor-tests/generated/LetExpr/LetExpr_getExpr.expected @@ -1 +1 @@ -| gen_let_expr.rs:5:8:5:31 | LetExpr | gen_let_expr.rs:5:22:5:31 | PathExpr | +| gen_let_expr.rs:5:8:5:31 | LetExpr | gen_let_expr.rs:5:22:5:31 | maybe_some | diff --git a/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt_getPat.expected b/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt_getPat.expected index 37462e8cfb64..93810df10e36 100644 --- a/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt_getPat.expected +++ b/rust/ql/test/extractor-tests/generated/LetStmt/LetStmt_getPat.expected @@ -1,6 +1,6 @@ -| gen_let_stmt.rs:5:5:5:15 | LetStmt | gen_let_stmt.rs:5:9:5:9 | IdentPat | -| gen_let_stmt.rs:6:5:6:20 | LetStmt | gen_let_stmt.rs:6:9:6:9 | IdentPat | -| gen_let_stmt.rs:7:5:7:15 | LetStmt | gen_let_stmt.rs:7:9:7:9 | IdentPat | -| gen_let_stmt.rs:8:5:8:10 | LetStmt | gen_let_stmt.rs:8:9:8:9 | IdentPat | +| gen_let_stmt.rs:5:5:5:15 | LetStmt | gen_let_stmt.rs:5:9:5:9 | x | +| gen_let_stmt.rs:6:5:6:20 | LetStmt | gen_let_stmt.rs:6:9:6:9 | x | +| gen_let_stmt.rs:7:5:7:15 | LetStmt | gen_let_stmt.rs:7:9:7:9 | x | +| gen_let_stmt.rs:8:5:8:10 | LetStmt | gen_let_stmt.rs:8:9:8:9 | x | | gen_let_stmt.rs:9:5:9:24 | LetStmt | gen_let_stmt.rs:9:9:9:14 | TuplePat | | gen_let_stmt.rs:10:5:12:6 | LetStmt | gen_let_stmt.rs:10:9:10:15 | TupleStructPat | diff --git a/rust/ql/test/extractor-tests/generated/MatchArm/MatchArm_getExpr.expected b/rust/ql/test/extractor-tests/generated/MatchArm/MatchArm_getExpr.expected index ea9eaff95307..493ea8d9bb03 100644 --- a/rust/ql/test/extractor-tests/generated/MatchArm/MatchArm_getExpr.expected +++ b/rust/ql/test/extractor-tests/generated/MatchArm/MatchArm_getExpr.expected @@ -1,4 +1,4 @@ -| gen_match_arm.rs:6:9:6:29 | MatchArm | gen_match_arm.rs:6:28:6:28 | PathExpr | +| gen_match_arm.rs:6:9:6:29 | MatchArm | gen_match_arm.rs:6:28:6:28 | y | | gen_match_arm.rs:7:9:7:26 | MatchArm | gen_match_arm.rs:7:25:7:25 | 0 | | gen_match_arm.rs:10:9:10:35 | MatchArm | gen_match_arm.rs:10:30:10:34 | ... / ... | | gen_match_arm.rs:11:9:11:15 | MatchArm | gen_match_arm.rs:11:14:11:14 | 0 | diff --git a/rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr_getExpr.expected b/rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr_getExpr.expected index 631592c910d6..924eb3f807fa 100644 --- a/rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr_getExpr.expected +++ b/rust/ql/test/extractor-tests/generated/MatchExpr/MatchExpr_getExpr.expected @@ -1,2 +1,2 @@ -| gen_match_expr.rs:5:5:8:5 | MatchExpr | gen_match_expr.rs:5:11:5:11 | PathExpr | -| gen_match_expr.rs:9:5:12:5 | MatchExpr | gen_match_expr.rs:9:11:9:11 | PathExpr | +| gen_match_expr.rs:5:5:8:5 | MatchExpr | gen_match_expr.rs:5:11:5:11 | x | +| gen_match_expr.rs:9:5:12:5 | MatchExpr | gen_match_expr.rs:9:11:9:11 | x | diff --git a/rust/ql/test/extractor-tests/generated/SlicePat/SlicePat_getPat.expected b/rust/ql/test/extractor-tests/generated/SlicePat/SlicePat_getPat.expected index 7c5355875f33..e874d3a22ee4 100644 --- a/rust/ql/test/extractor-tests/generated/SlicePat/SlicePat_getPat.expected +++ b/rust/ql/test/extractor-tests/generated/SlicePat/SlicePat_getPat.expected @@ -6,8 +6,8 @@ | gen_slice_pat.rs:7:9:7:18 | SlicePat | 0 | gen_slice_pat.rs:7:10:7:10 | LiteralPat | | gen_slice_pat.rs:7:9:7:18 | SlicePat | 1 | gen_slice_pat.rs:7:13:7:13 | LiteralPat | | gen_slice_pat.rs:7:9:7:18 | SlicePat | 2 | gen_slice_pat.rs:7:16:7:17 | RestPat | -| gen_slice_pat.rs:8:9:8:24 | SlicePat | 0 | gen_slice_pat.rs:8:10:8:10 | IdentPat | -| gen_slice_pat.rs:8:9:8:24 | SlicePat | 1 | gen_slice_pat.rs:8:13:8:13 | IdentPat | +| gen_slice_pat.rs:8:9:8:24 | SlicePat | 0 | gen_slice_pat.rs:8:10:8:10 | x | +| gen_slice_pat.rs:8:9:8:24 | SlicePat | 1 | gen_slice_pat.rs:8:13:8:13 | y | | gen_slice_pat.rs:8:9:8:24 | SlicePat | 2 | gen_slice_pat.rs:8:16:8:17 | RestPat | -| gen_slice_pat.rs:8:9:8:24 | SlicePat | 3 | gen_slice_pat.rs:8:20:8:20 | IdentPat | +| gen_slice_pat.rs:8:9:8:24 | SlicePat | 3 | gen_slice_pat.rs:8:20:8:20 | z | | gen_slice_pat.rs:8:9:8:24 | SlicePat | 4 | gen_slice_pat.rs:8:23:8:23 | LiteralPat | diff --git a/rust/ql/test/extractor-tests/generated/TuplePat/TuplePat_getField.expected b/rust/ql/test/extractor-tests/generated/TuplePat/TuplePat_getField.expected index 8f42a4e1393e..59d028b43ca9 100644 --- a/rust/ql/test/extractor-tests/generated/TuplePat/TuplePat_getField.expected +++ b/rust/ql/test/extractor-tests/generated/TuplePat/TuplePat_getField.expected @@ -1,6 +1,6 @@ -| gen_tuple_pat.rs:5:9:5:14 | TuplePat | 0 | gen_tuple_pat.rs:5:10:5:10 | IdentPat | -| gen_tuple_pat.rs:5:9:5:14 | TuplePat | 1 | gen_tuple_pat.rs:5:13:5:13 | IdentPat | -| gen_tuple_pat.rs:6:9:6:22 | TuplePat | 0 | gen_tuple_pat.rs:6:10:6:10 | IdentPat | -| gen_tuple_pat.rs:6:9:6:22 | TuplePat | 1 | gen_tuple_pat.rs:6:13:6:13 | IdentPat | +| gen_tuple_pat.rs:5:9:5:14 | TuplePat | 0 | gen_tuple_pat.rs:5:10:5:10 | x | +| gen_tuple_pat.rs:5:9:5:14 | TuplePat | 1 | gen_tuple_pat.rs:5:13:5:13 | y | +| gen_tuple_pat.rs:6:9:6:22 | TuplePat | 0 | gen_tuple_pat.rs:6:10:6:10 | a | +| gen_tuple_pat.rs:6:9:6:22 | TuplePat | 1 | gen_tuple_pat.rs:6:13:6:13 | b | | gen_tuple_pat.rs:6:9:6:22 | TuplePat | 2 | gen_tuple_pat.rs:6:16:6:17 | RestPat | -| gen_tuple_pat.rs:6:9:6:22 | TuplePat | 3 | gen_tuple_pat.rs:6:21:6:21 | IdentPat | +| gen_tuple_pat.rs:6:9:6:22 | TuplePat | 3 | gen_tuple_pat.rs:6:21:6:21 | z | diff --git a/rust/ql/test/extractor-tests/utf8/ast.expected b/rust/ql/test/extractor-tests/utf8/ast.expected index 2ebf1fb7f03d..5f353287fbb1 100644 --- a/rust/ql/test/extractor-tests/utf8/ast.expected +++ b/rust/ql/test/extractor-tests/utf8/ast.expected @@ -34,6 +34,6 @@ | utf8-identifiers.rs:10:15:12:1 | BlockExpr | | utf8-identifiers.rs:10:15:12:1 | StmtList | | utf8-identifiers.rs:11:5:11:24 | LetStmt | -| utf8-identifiers.rs:11:9:11:9 | IdentPat | | utf8-identifiers.rs:11:9:11:9 | Name | +| utf8-identifiers.rs:11:9:11:9 | \u03b1 | | utf8-identifiers.rs:11:14:11:23 | 0.00001f64 | diff --git a/rust/ql/test/library-tests/controlflow/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/library-tests/controlflow/CONSISTENCY/CfgConsistency.expected index a997162e6cdc..ec8ec04bf3ea 100644 --- a/rust/ql/test/library-tests/controlflow/CONSISTENCY/CfgConsistency.expected +++ b/rust/ql/test/library-tests/controlflow/CONSISTENCY/CfgConsistency.expected @@ -1,5 +1,5 @@ deadEnd -| test.rs:55:13:55:17 | IdentPat | +| test.rs:55:13:55:17 | b | | test.rs:224:28:224:33 | ... < ... | | test.rs:239:30:239:48 | BlockExpr | scopeNoFirst diff --git a/rust/ql/test/library-tests/controlflow/Cfg.expected b/rust/ql/test/library-tests/controlflow/Cfg.expected index 43cc44ea2cbe..d0ab3bd10d63 100644 --- a/rust/ql/test/library-tests/controlflow/Cfg.expected +++ b/rust/ql/test/library-tests/controlflow/Cfg.expected @@ -13,9 +13,9 @@ | test.rs:3:21:3:22 | 42 | test.rs:3:5:3:23 | CallExpr | | | test.rs:8:5:24:5 | enter test_break_and_continue | test.rs:9:9:9:22 | LetStmt | | | test.rs:8:5:24:5 | exit test_break_and_continue (normal) | test.rs:8:5:24:5 | exit test_break_and_continue | | -| test.rs:9:9:9:22 | LetStmt | test.rs:9:21:9:21 | PathExpr | | -| test.rs:9:13:9:17 | IdentPat | test.rs:10:9:22:9 | ExprStmt | match, no-match | -| test.rs:9:21:9:21 | PathExpr | test.rs:9:13:9:17 | IdentPat | | +| test.rs:9:9:9:22 | LetStmt | test.rs:9:21:9:21 | n | | +| test.rs:9:13:9:17 | i | test.rs:10:9:22:9 | ExprStmt | match, no-match | +| test.rs:9:21:9:21 | n | test.rs:9:13:9:17 | i | | | test.rs:10:9:22:9 | ExprStmt | test.rs:11:13:11:24 | ExprStmt | | | test.rs:10:9:22:9 | LoopExpr | test.rs:23:9:23:20 | ExprStmt | | | test.rs:10:14:22:9 | BlockExpr | test.rs:11:13:11:24 | ExprStmt | | @@ -67,15 +67,15 @@ | test.rs:27:9:36:9 | LoopExpr | test.rs:37:9:37:12 | true | | | test.rs:27:22:36:9 | BlockExpr | test.rs:29:17:33:17 | ExprStmt | | | test.rs:28:13:35:13 | LoopExpr | test.rs:27:22:36:9 | BlockExpr | | -| test.rs:29:17:33:17 | ExprStmt | test.rs:29:20:29:20 | PathExpr | | +| test.rs:29:17:33:17 | ExprStmt | test.rs:29:20:29:20 | b | | | test.rs:29:17:33:17 | IfExpr | test.rs:34:17:34:29 | ExprStmt | | -| test.rs:29:20:29:20 | PathExpr | test.rs:30:21:30:26 | ExprStmt | true | -| test.rs:29:20:29:20 | PathExpr | test.rs:31:27:31:27 | PathExpr | false | +| test.rs:29:20:29:20 | b | test.rs:30:21:30:26 | ExprStmt | true | +| test.rs:29:20:29:20 | b | test.rs:31:27:31:27 | b | false | | test.rs:30:21:30:25 | BreakExpr | test.rs:28:13:35:13 | LoopExpr | break | | test.rs:30:21:30:26 | ExprStmt | test.rs:30:21:30:25 | BreakExpr | | | test.rs:31:24:33:17 | IfExpr | test.rs:29:17:33:17 | IfExpr | | -| test.rs:31:27:31:27 | PathExpr | test.rs:31:24:33:17 | IfExpr | false | -| test.rs:31:27:31:27 | PathExpr | test.rs:32:21:32:33 | ExprStmt | true | +| test.rs:31:27:31:27 | b | test.rs:31:24:33:17 | IfExpr | false | +| test.rs:31:27:31:27 | b | test.rs:32:21:32:33 | ExprStmt | true | | test.rs:32:21:32:32 | BreakExpr | test.rs:27:9:36:9 | LoopExpr | break('outer) | | test.rs:32:21:32:33 | ExprStmt | test.rs:32:21:32:32 | BreakExpr | | | test.rs:34:17:34:28 | BreakExpr | test.rs:28:13:35:13 | LoopExpr | break('inner) | @@ -84,50 +84,50 @@ | test.rs:40:5:52:5 | enter test_continue_with_labels | test.rs:42:13:42:14 | ExprStmt | | | test.rs:42:13:42:13 | 1 | test.rs:44:17:48:17 | ExprStmt | | | test.rs:42:13:42:14 | ExprStmt | test.rs:42:13:42:13 | 1 | | -| test.rs:44:17:48:17 | ExprStmt | test.rs:44:20:44:20 | PathExpr | | +| test.rs:44:17:48:17 | ExprStmt | test.rs:44:20:44:20 | b | | | test.rs:44:17:48:17 | IfExpr | test.rs:49:17:49:32 | ExprStmt | | -| test.rs:44:20:44:20 | PathExpr | test.rs:45:21:45:29 | ExprStmt | true | -| test.rs:44:20:44:20 | PathExpr | test.rs:46:27:46:27 | PathExpr | false | +| test.rs:44:20:44:20 | b | test.rs:45:21:45:29 | ExprStmt | true | +| test.rs:44:20:44:20 | b | test.rs:46:27:46:27 | b | false | | test.rs:45:21:45:28 | ContinueExpr | test.rs:44:17:48:17 | ExprStmt | continue | | test.rs:45:21:45:29 | ExprStmt | test.rs:45:21:45:28 | ContinueExpr | | | test.rs:46:24:48:17 | IfExpr | test.rs:44:17:48:17 | IfExpr | | -| test.rs:46:27:46:27 | PathExpr | test.rs:46:24:48:17 | IfExpr | false | -| test.rs:46:27:46:27 | PathExpr | test.rs:47:21:47:36 | ExprStmt | true | +| test.rs:46:27:46:27 | b | test.rs:46:24:48:17 | IfExpr | false | +| test.rs:46:27:46:27 | b | test.rs:47:21:47:36 | ExprStmt | true | | test.rs:47:21:47:35 | ContinueExpr | test.rs:42:13:42:14 | ExprStmt | continue('outer) | | test.rs:47:21:47:36 | ExprStmt | test.rs:47:21:47:35 | ContinueExpr | | | test.rs:49:17:49:31 | ContinueExpr | test.rs:44:17:48:17 | ExprStmt | continue('inner) | | test.rs:49:17:49:32 | ExprStmt | test.rs:49:17:49:31 | ContinueExpr | | | test.rs:54:5:60:5 | enter test_while | test.rs:55:9:55:25 | LetStmt | | | test.rs:55:9:55:25 | LetStmt | test.rs:55:21:55:24 | true | | -| test.rs:55:21:55:24 | true | test.rs:55:13:55:17 | IdentPat | | +| test.rs:55:21:55:24 | true | test.rs:55:13:55:17 | b | | | test.rs:69:1:72:1 | enter test_nested_function | test.rs:70:5:70:28 | LetStmt | | | test.rs:69:1:72:1 | exit test_nested_function (normal) | test.rs:69:1:72:1 | exit test_nested_function | | | test.rs:69:40:72:1 | BlockExpr | test.rs:69:1:72:1 | exit test_nested_function (normal) | | | test.rs:70:5:70:28 | LetStmt | test.rs:70:19:70:27 | ClosureExpr | | -| test.rs:70:9:70:15 | IdentPat | test.rs:71:5:71:11 | PathExpr | match, no-match | -| test.rs:70:19:70:27 | ClosureExpr | test.rs:70:9:70:15 | IdentPat | | -| test.rs:70:19:70:27 | enter ClosureExpr | test.rs:70:23:70:23 | PathExpr | | +| test.rs:70:9:70:15 | add_one | test.rs:71:5:71:11 | add_one | match, no-match | +| test.rs:70:19:70:27 | ClosureExpr | test.rs:70:9:70:15 | add_one | | +| test.rs:70:19:70:27 | enter ClosureExpr | test.rs:70:23:70:23 | i | | | test.rs:70:19:70:27 | exit ClosureExpr (normal) | test.rs:70:19:70:27 | exit ClosureExpr | | -| test.rs:70:23:70:23 | PathExpr | test.rs:70:27:70:27 | 1 | | +| test.rs:70:23:70:23 | i | test.rs:70:27:70:27 | 1 | | | test.rs:70:23:70:27 | ... + ... | test.rs:70:19:70:27 | exit ClosureExpr (normal) | | | test.rs:70:27:70:27 | 1 | test.rs:70:23:70:27 | ... + ... | | -| test.rs:71:5:71:11 | PathExpr | test.rs:71:13:71:19 | PathExpr | | +| test.rs:71:5:71:11 | add_one | test.rs:71:13:71:19 | add_one | | | test.rs:71:5:71:23 | CallExpr | test.rs:69:40:72:1 | BlockExpr | | -| test.rs:71:13:71:19 | PathExpr | test.rs:71:21:71:21 | PathExpr | | +| test.rs:71:13:71:19 | add_one | test.rs:71:21:71:21 | n | | | test.rs:71:13:71:22 | CallExpr | test.rs:71:5:71:23 | CallExpr | | -| test.rs:71:21:71:21 | PathExpr | test.rs:71:13:71:22 | CallExpr | | -| test.rs:76:5:82:5 | enter test_if_else | test.rs:77:12:77:12 | PathExpr | | +| test.rs:71:21:71:21 | n | test.rs:71:13:71:22 | CallExpr | | +| test.rs:76:5:82:5 | enter test_if_else | test.rs:77:12:77:12 | n | | | test.rs:76:5:82:5 | exit test_if_else (normal) | test.rs:76:5:82:5 | exit test_if_else | | | test.rs:76:36:82:5 | BlockExpr | test.rs:76:5:82:5 | exit test_if_else (normal) | | | test.rs:77:9:81:9 | IfExpr | test.rs:76:36:82:5 | BlockExpr | | -| test.rs:77:12:77:12 | PathExpr | test.rs:77:17:77:17 | 0 | | +| test.rs:77:12:77:12 | n | test.rs:77:17:77:17 | 0 | | | test.rs:77:12:77:17 | ... <= ... | test.rs:78:13:78:13 | 0 | true | -| test.rs:77:12:77:17 | ... <= ... | test.rs:80:13:80:13 | PathExpr | false | +| test.rs:77:12:77:17 | ... <= ... | test.rs:80:13:80:13 | n | false | | test.rs:77:17:77:17 | 0 | test.rs:77:12:77:17 | ... <= ... | | | test.rs:77:19:79:9 | BlockExpr | test.rs:77:9:81:9 | IfExpr | | | test.rs:78:13:78:13 | 0 | test.rs:77:19:79:9 | BlockExpr | | | test.rs:79:16:81:9 | BlockExpr | test.rs:77:9:81:9 | IfExpr | | -| test.rs:80:13:80:13 | PathExpr | test.rs:80:17:80:17 | 1 | | +| test.rs:80:13:80:13 | n | test.rs:80:17:80:17 | 1 | | | test.rs:80:13:80:17 | ... - ... | test.rs:79:16:81:9 | BlockExpr | | | test.rs:80:17:80:17 | 1 | test.rs:80:13:80:17 | ... - ... | | | test.rs:84:5:90:5 | enter test_if_let_else | test.rs:85:12:85:26 | LetExpr | | @@ -135,10 +135,10 @@ | test.rs:84:48:90:5 | BlockExpr | test.rs:84:5:90:5 | exit test_if_let_else (normal) | | | test.rs:85:9:89:9 | IfExpr | test.rs:84:48:90:5 | BlockExpr | | | test.rs:85:12:85:26 | LetExpr | test.rs:85:16:85:22 | TupleStructPat | | -| test.rs:85:16:85:22 | TupleStructPat | test.rs:86:13:86:13 | PathExpr | match | +| test.rs:85:16:85:22 | TupleStructPat | test.rs:86:13:86:13 | n | match | | test.rs:85:16:85:22 | TupleStructPat | test.rs:88:13:88:13 | 0 | no-match | | test.rs:85:28:87:9 | BlockExpr | test.rs:85:9:89:9 | IfExpr | | -| test.rs:86:13:86:13 | PathExpr | test.rs:85:28:87:9 | BlockExpr | | +| test.rs:86:13:86:13 | n | test.rs:85:28:87:9 | BlockExpr | | | test.rs:87:16:89:9 | BlockExpr | test.rs:85:9:89:9 | IfExpr | | | test.rs:88:13:88:13 | 0 | test.rs:87:16:89:9 | BlockExpr | | | test.rs:92:5:97:5 | enter test_if_let | test.rs:93:9:95:9 | ExprStmt | | @@ -148,9 +148,9 @@ | test.rs:93:9:95:9 | IfExpr | test.rs:96:9:96:9 | 0 | | | test.rs:93:12:93:26 | LetExpr | test.rs:93:16:93:22 | TupleStructPat | | | test.rs:93:16:93:22 | TupleStructPat | test.rs:93:9:95:9 | IfExpr | no-match | -| test.rs:93:16:93:22 | TupleStructPat | test.rs:94:13:94:13 | PathExpr | match | +| test.rs:93:16:93:22 | TupleStructPat | test.rs:94:13:94:13 | n | match | | test.rs:93:28:95:9 | BlockExpr | test.rs:93:9:95:9 | IfExpr | | -| test.rs:94:13:94:13 | PathExpr | test.rs:93:28:95:9 | BlockExpr | | +| test.rs:94:13:94:13 | n | test.rs:93:28:95:9 | BlockExpr | | | test.rs:96:9:96:9 | 0 | test.rs:92:43:97:5 | BlockExpr | | | test.rs:99:5:105:5 | enter test_nested_if | test.rs:100:16:100:16 | PathExpr | | | test.rs:99:5:105:5 | exit test_nested_if (normal) | test.rs:99:5:105:5 | exit test_nested_if | | @@ -160,30 +160,30 @@ | test.rs:100:12:100:49 | ParenExpr | test.rs:103:13:103:13 | 0 | false | | test.rs:100:13:100:48 | IfExpr | test.rs:100:12:100:49 | ParenExpr | | | test.rs:100:16:100:16 | PathExpr | test.rs:100:20:100:20 | 0 | | -| test.rs:100:16:100:20 | ... < ... | test.rs:100:24:100:24 | PathExpr | true | -| test.rs:100:16:100:20 | ... < ... | test.rs:100:41:100:41 | PathExpr | false | +| test.rs:100:16:100:20 | ... < ... | test.rs:100:24:100:24 | a | true | +| test.rs:100:16:100:20 | ... < ... | test.rs:100:41:100:41 | a | false | | test.rs:100:20:100:20 | 0 | test.rs:100:16:100:20 | ... < ... | | | test.rs:100:22:100:32 | BlockExpr | test.rs:100:13:100:48 | IfExpr | | -| test.rs:100:24:100:24 | PathExpr | test.rs:100:29:100:30 | 10 | | +| test.rs:100:24:100:24 | a | test.rs:100:29:100:30 | 10 | | | test.rs:100:24:100:30 | ... < ... | test.rs:100:22:100:32 | BlockExpr | | | test.rs:100:28:100:30 | - ... | test.rs:100:24:100:30 | ... < ... | | | test.rs:100:29:100:30 | 10 | test.rs:100:28:100:30 | - ... | | | test.rs:100:39:100:48 | BlockExpr | test.rs:100:13:100:48 | IfExpr | | -| test.rs:100:41:100:41 | PathExpr | test.rs:100:45:100:46 | 10 | | +| test.rs:100:41:100:41 | a | test.rs:100:45:100:46 | 10 | | | test.rs:100:41:100:46 | ... > ... | test.rs:100:39:100:48 | BlockExpr | | | test.rs:100:45:100:46 | 10 | test.rs:100:41:100:46 | ... > ... | | | test.rs:100:51:102:9 | BlockExpr | test.rs:100:9:104:9 | IfExpr | | | test.rs:101:13:101:13 | 1 | test.rs:100:51:102:9 | BlockExpr | | | test.rs:102:16:104:9 | BlockExpr | test.rs:100:9:104:9 | IfExpr | | | test.rs:103:13:103:13 | 0 | test.rs:102:16:104:9 | BlockExpr | | -| test.rs:107:5:116:5 | enter test_nested_if_match | test.rs:108:19:108:19 | PathExpr | | +| test.rs:107:5:116:5 | enter test_nested_if_match | test.rs:108:19:108:19 | a | | | test.rs:107:5:116:5 | exit test_nested_if_match (normal) | test.rs:107:5:116:5 | exit test_nested_if_match | | | test.rs:107:44:116:5 | BlockExpr | test.rs:107:5:116:5 | exit test_nested_if_match (normal) | | | test.rs:108:9:115:9 | IfExpr | test.rs:107:44:116:5 | BlockExpr | | | test.rs:108:12:111:10 | ParenExpr | test.rs:112:13:112:13 | 1 | true | | test.rs:108:12:111:10 | ParenExpr | test.rs:114:13:114:13 | 0 | false | | test.rs:108:13:111:9 | MatchExpr | test.rs:108:12:111:10 | ParenExpr | | -| test.rs:108:19:108:19 | PathExpr | test.rs:109:13:109:13 | LiteralPat | | +| test.rs:108:19:108:19 | a | test.rs:109:13:109:13 | LiteralPat | | | test.rs:109:13:109:13 | LiteralPat | test.rs:109:18:109:21 | true | match | | test.rs:109:13:109:13 | LiteralPat | test.rs:110:13:110:13 | WildcardPat | no-match | | test.rs:109:18:109:21 | true | test.rs:108:13:111:9 | MatchExpr | | @@ -199,9 +199,9 @@ | test.rs:119:9:126:9 | IfExpr | test.rs:118:44:127:5 | BlockExpr | | | test.rs:119:12:122:9 | BlockExpr | test.rs:123:13:123:13 | 1 | true | | test.rs:119:12:122:9 | BlockExpr | test.rs:125:13:125:13 | 0 | false | -| test.rs:120:13:120:14 | TupleExpr | test.rs:121:13:121:13 | PathExpr | | +| test.rs:120:13:120:14 | TupleExpr | test.rs:121:13:121:13 | a | | | test.rs:120:13:120:15 | ExprStmt | test.rs:120:13:120:14 | TupleExpr | | -| test.rs:121:13:121:13 | PathExpr | test.rs:121:17:121:17 | 0 | | +| test.rs:121:13:121:13 | a | test.rs:121:17:121:17 | 0 | | | test.rs:121:13:121:17 | ... > ... | test.rs:119:12:122:9 | BlockExpr | false, true | | test.rs:121:17:121:17 | 0 | test.rs:121:13:121:17 | ... > ... | | | test.rs:122:11:124:9 | BlockExpr | test.rs:119:9:126:9 | IfExpr | | @@ -212,10 +212,10 @@ | test.rs:129:5:136:5 | exit test_if_assignment (normal) | test.rs:129:5:136:5 | exit test_if_assignment | | | test.rs:129:42:136:5 | BlockExpr | test.rs:129:5:136:5 | exit test_if_assignment (normal) | | | test.rs:130:9:130:26 | LetStmt | test.rs:130:21:130:25 | false | | -| test.rs:130:13:130:17 | IdentPat | test.rs:131:12:131:12 | PathExpr | match, no-match | -| test.rs:130:21:130:25 | false | test.rs:130:13:130:17 | IdentPat | | +| test.rs:130:13:130:17 | x | test.rs:131:12:131:12 | x | match, no-match | +| test.rs:130:21:130:25 | false | test.rs:130:13:130:17 | x | | | test.rs:131:9:135:9 | IfExpr | test.rs:129:42:136:5 | BlockExpr | | -| test.rs:131:12:131:12 | PathExpr | test.rs:131:16:131:19 | true | | +| test.rs:131:12:131:12 | x | test.rs:131:16:131:19 | true | | | test.rs:131:12:131:19 | ... = ... | test.rs:132:13:132:13 | 1 | true | | test.rs:131:12:131:19 | ... = ... | test.rs:134:13:134:13 | 0 | false | | test.rs:131:16:131:19 | true | test.rs:131:12:131:19 | ... = ... | | @@ -232,19 +232,19 @@ | test.rs:139:13:144:9 | LoopExpr | test.rs:139:12:144:10 | ParenExpr | | | test.rs:139:18:144:9 | BlockExpr | test.rs:140:13:142:14 | ExprStmt | | | test.rs:140:13:142:13 | IfExpr | test.rs:143:13:143:19 | ExprStmt | | -| test.rs:140:13:142:14 | ExprStmt | test.rs:140:16:140:16 | PathExpr | | -| test.rs:140:16:140:16 | PathExpr | test.rs:140:20:140:20 | 0 | | +| test.rs:140:13:142:14 | ExprStmt | test.rs:140:16:140:16 | a | | +| test.rs:140:16:140:16 | a | test.rs:140:20:140:20 | 0 | | | test.rs:140:16:140:20 | ... > ... | test.rs:140:13:142:13 | IfExpr | false | | test.rs:140:16:140:20 | ... > ... | test.rs:141:17:141:29 | ExprStmt | true | | test.rs:140:20:140:20 | 0 | test.rs:140:16:140:20 | ... > ... | | | test.rs:141:17:141:28 | BreakExpr | test.rs:139:13:144:9 | LoopExpr | break | -| test.rs:141:17:141:29 | ExprStmt | test.rs:141:23:141:23 | PathExpr | | -| test.rs:141:23:141:23 | PathExpr | test.rs:141:27:141:28 | 10 | | +| test.rs:141:17:141:29 | ExprStmt | test.rs:141:23:141:23 | a | | +| test.rs:141:23:141:23 | a | test.rs:141:27:141:28 | 10 | | | test.rs:141:23:141:28 | ... > ... | test.rs:141:17:141:28 | BreakExpr | | | test.rs:141:27:141:28 | 10 | test.rs:141:23:141:28 | ... > ... | | -| test.rs:143:13:143:13 | PathExpr | test.rs:143:17:143:18 | 10 | | +| test.rs:143:13:143:13 | a | test.rs:143:17:143:18 | 10 | | | test.rs:143:13:143:18 | ... < ... | test.rs:139:18:144:9 | BlockExpr | | -| test.rs:143:13:143:19 | ExprStmt | test.rs:143:13:143:13 | PathExpr | | +| test.rs:143:13:143:19 | ExprStmt | test.rs:143:13:143:13 | a | | | test.rs:143:17:143:18 | 10 | test.rs:143:13:143:18 | ... < ... | | | test.rs:144:12:146:9 | BlockExpr | test.rs:139:9:148:9 | IfExpr | | | test.rs:145:13:145:13 | 1 | test.rs:144:12:146:9 | BlockExpr | | @@ -259,19 +259,19 @@ | test.rs:152:13:157:9 | LoopExpr | test.rs:152:12:157:10 | ParenExpr | | | test.rs:152:26:157:9 | BlockExpr | test.rs:153:13:155:14 | ExprStmt | | | test.rs:153:13:155:13 | IfExpr | test.rs:156:13:156:19 | ExprStmt | | -| test.rs:153:13:155:14 | ExprStmt | test.rs:153:16:153:16 | PathExpr | | -| test.rs:153:16:153:16 | PathExpr | test.rs:153:20:153:20 | 0 | | +| test.rs:153:13:155:14 | ExprStmt | test.rs:153:16:153:16 | a | | +| test.rs:153:16:153:16 | a | test.rs:153:20:153:20 | 0 | | | test.rs:153:16:153:20 | ... > ... | test.rs:153:13:155:13 | IfExpr | false | | test.rs:153:16:153:20 | ... > ... | test.rs:154:17:154:36 | ExprStmt | true | | test.rs:153:20:153:20 | 0 | test.rs:153:16:153:20 | ... > ... | | | test.rs:154:17:154:35 | BreakExpr | test.rs:152:13:157:9 | LoopExpr | break('label) | -| test.rs:154:17:154:36 | ExprStmt | test.rs:154:30:154:30 | PathExpr | | -| test.rs:154:30:154:30 | PathExpr | test.rs:154:34:154:35 | 10 | | +| test.rs:154:17:154:36 | ExprStmt | test.rs:154:30:154:30 | a | | +| test.rs:154:30:154:30 | a | test.rs:154:34:154:35 | 10 | | | test.rs:154:30:154:35 | ... > ... | test.rs:154:17:154:35 | BreakExpr | | | test.rs:154:34:154:35 | 10 | test.rs:154:30:154:35 | ... > ... | | -| test.rs:156:13:156:13 | PathExpr | test.rs:156:17:156:18 | 10 | | +| test.rs:156:13:156:13 | a | test.rs:156:17:156:18 | 10 | | | test.rs:156:13:156:18 | ... < ... | test.rs:152:26:157:9 | BlockExpr | | -| test.rs:156:13:156:19 | ExprStmt | test.rs:156:13:156:13 | PathExpr | | +| test.rs:156:13:156:19 | ExprStmt | test.rs:156:13:156:13 | a | | | test.rs:156:17:156:18 | 10 | test.rs:156:13:156:18 | ... < ... | | | test.rs:157:12:159:9 | BlockExpr | test.rs:152:9:161:9 | IfExpr | | | test.rs:158:13:158:13 | 1 | test.rs:157:12:159:9 | BlockExpr | | @@ -280,72 +280,72 @@ | test.rs:164:5:172:5 | enter test_labelled_block | test.rs:166:13:166:31 | ExprStmt | | | test.rs:164:5:172:5 | exit test_labelled_block (normal) | test.rs:164:5:172:5 | exit test_labelled_block | | | test.rs:166:13:166:30 | BreakExpr | test.rs:164:5:172:5 | exit test_labelled_block (normal) | break('block) | -| test.rs:166:13:166:31 | ExprStmt | test.rs:166:26:166:26 | PathExpr | | -| test.rs:166:26:166:26 | PathExpr | test.rs:166:30:166:30 | 0 | | +| test.rs:166:13:166:31 | ExprStmt | test.rs:166:26:166:26 | a | | +| test.rs:166:26:166:26 | a | test.rs:166:30:166:30 | 0 | | | test.rs:166:26:166:30 | ... > ... | test.rs:166:13:166:30 | BreakExpr | | | test.rs:166:30:166:30 | 0 | test.rs:166:26:166:30 | ... > ... | | | test.rs:177:5:180:5 | enter test_and_operator | test.rs:178:9:178:28 | LetStmt | | | test.rs:177:5:180:5 | exit test_and_operator (normal) | test.rs:177:5:180:5 | exit test_and_operator | | | test.rs:177:61:180:5 | BlockExpr | test.rs:177:5:180:5 | exit test_and_operator (normal) | | | test.rs:178:9:178:28 | LetStmt | test.rs:178:17:178:27 | ... && ... | | -| test.rs:178:13:178:13 | IdentPat | test.rs:179:9:179:9 | PathExpr | match, no-match | -| test.rs:178:17:178:17 | PathExpr | test.rs:178:13:178:13 | IdentPat | false | -| test.rs:178:17:178:17 | PathExpr | test.rs:178:22:178:22 | PathExpr | true | -| test.rs:178:17:178:22 | ... && ... | test.rs:178:17:178:17 | PathExpr | | +| test.rs:178:13:178:13 | d | test.rs:179:9:179:9 | d | match, no-match | +| test.rs:178:17:178:17 | a | test.rs:178:13:178:13 | d | false | +| test.rs:178:17:178:17 | a | test.rs:178:22:178:22 | b | true | +| test.rs:178:17:178:22 | ... && ... | test.rs:178:17:178:17 | a | | | test.rs:178:17:178:27 | ... && ... | test.rs:178:17:178:22 | ... && ... | | -| test.rs:178:22:178:22 | PathExpr | test.rs:178:13:178:13 | IdentPat | false | -| test.rs:178:22:178:22 | PathExpr | test.rs:178:27:178:27 | PathExpr | true | -| test.rs:178:27:178:27 | PathExpr | test.rs:178:13:178:13 | IdentPat | | -| test.rs:179:9:179:9 | PathExpr | test.rs:177:61:180:5 | BlockExpr | | +| test.rs:178:22:178:22 | b | test.rs:178:13:178:13 | d | false | +| test.rs:178:22:178:22 | b | test.rs:178:27:178:27 | c | true | +| test.rs:178:27:178:27 | c | test.rs:178:13:178:13 | d | | +| test.rs:179:9:179:9 | d | test.rs:177:61:180:5 | BlockExpr | | | test.rs:182:5:185:5 | enter test_or_operator | test.rs:183:9:183:28 | LetStmt | | | test.rs:182:5:185:5 | exit test_or_operator (normal) | test.rs:182:5:185:5 | exit test_or_operator | | | test.rs:182:60:185:5 | BlockExpr | test.rs:182:5:185:5 | exit test_or_operator (normal) | | | test.rs:183:9:183:28 | LetStmt | test.rs:183:17:183:27 | ... \|\| ... | | -| test.rs:183:13:183:13 | IdentPat | test.rs:184:9:184:9 | PathExpr | match, no-match | -| test.rs:183:17:183:17 | PathExpr | test.rs:183:13:183:13 | IdentPat | true | -| test.rs:183:17:183:17 | PathExpr | test.rs:183:22:183:22 | PathExpr | false | -| test.rs:183:17:183:22 | ... \|\| ... | test.rs:183:17:183:17 | PathExpr | | +| test.rs:183:13:183:13 | d | test.rs:184:9:184:9 | d | match, no-match | +| test.rs:183:17:183:17 | a | test.rs:183:13:183:13 | d | true | +| test.rs:183:17:183:17 | a | test.rs:183:22:183:22 | b | false | +| test.rs:183:17:183:22 | ... \|\| ... | test.rs:183:17:183:17 | a | | | test.rs:183:17:183:27 | ... \|\| ... | test.rs:183:17:183:22 | ... \|\| ... | | -| test.rs:183:22:183:22 | PathExpr | test.rs:183:13:183:13 | IdentPat | true | -| test.rs:183:22:183:22 | PathExpr | test.rs:183:27:183:27 | PathExpr | false | -| test.rs:183:27:183:27 | PathExpr | test.rs:183:13:183:13 | IdentPat | | -| test.rs:184:9:184:9 | PathExpr | test.rs:182:60:185:5 | BlockExpr | | +| test.rs:183:22:183:22 | b | test.rs:183:13:183:13 | d | true | +| test.rs:183:22:183:22 | b | test.rs:183:27:183:27 | c | false | +| test.rs:183:27:183:27 | c | test.rs:183:13:183:13 | d | | +| test.rs:184:9:184:9 | d | test.rs:182:60:185:5 | BlockExpr | | | test.rs:187:5:190:5 | enter test_or_operator_2 | test.rs:188:9:188:36 | LetStmt | | | test.rs:187:5:190:5 | exit test_or_operator_2 (normal) | test.rs:187:5:190:5 | exit test_or_operator_2 | | | test.rs:187:61:190:5 | BlockExpr | test.rs:187:5:190:5 | exit test_or_operator_2 (normal) | | | test.rs:188:9:188:36 | LetStmt | test.rs:188:17:188:35 | ... \|\| ... | | -| test.rs:188:13:188:13 | IdentPat | test.rs:189:9:189:9 | PathExpr | match, no-match | -| test.rs:188:17:188:17 | PathExpr | test.rs:188:13:188:13 | IdentPat | true | -| test.rs:188:17:188:17 | PathExpr | test.rs:188:23:188:23 | PathExpr | false | -| test.rs:188:17:188:30 | ... \|\| ... | test.rs:188:17:188:17 | PathExpr | | +| test.rs:188:13:188:13 | d | test.rs:189:9:189:9 | d | match, no-match | +| test.rs:188:17:188:17 | a | test.rs:188:13:188:13 | d | true | +| test.rs:188:17:188:17 | a | test.rs:188:23:188:23 | b | false | +| test.rs:188:17:188:30 | ... \|\| ... | test.rs:188:17:188:17 | a | | | test.rs:188:17:188:35 | ... \|\| ... | test.rs:188:17:188:30 | ... \|\| ... | | -| test.rs:188:22:188:30 | ParenExpr | test.rs:188:13:188:13 | IdentPat | true | -| test.rs:188:22:188:30 | ParenExpr | test.rs:188:35:188:35 | PathExpr | false | -| test.rs:188:23:188:23 | PathExpr | test.rs:188:28:188:29 | 28 | | +| test.rs:188:22:188:30 | ParenExpr | test.rs:188:13:188:13 | d | true | +| test.rs:188:22:188:30 | ParenExpr | test.rs:188:35:188:35 | c | false | +| test.rs:188:23:188:23 | b | test.rs:188:28:188:29 | 28 | | | test.rs:188:23:188:29 | ... == ... | test.rs:188:22:188:30 | ParenExpr | | | test.rs:188:28:188:29 | 28 | test.rs:188:23:188:29 | ... == ... | | -| test.rs:188:35:188:35 | PathExpr | test.rs:188:13:188:13 | IdentPat | | -| test.rs:189:9:189:9 | PathExpr | test.rs:187:61:190:5 | BlockExpr | | +| test.rs:188:35:188:35 | c | test.rs:188:13:188:13 | d | | +| test.rs:189:9:189:9 | d | test.rs:187:61:190:5 | BlockExpr | | | test.rs:192:5:195:5 | enter test_not_operator | test.rs:193:9:193:19 | LetStmt | | | test.rs:192:5:195:5 | exit test_not_operator (normal) | test.rs:192:5:195:5 | exit test_not_operator | | | test.rs:192:43:195:5 | BlockExpr | test.rs:192:5:195:5 | exit test_not_operator (normal) | | -| test.rs:193:9:193:19 | LetStmt | test.rs:193:18:193:18 | PathExpr | | -| test.rs:193:13:193:13 | IdentPat | test.rs:194:9:194:9 | PathExpr | match, no-match | -| test.rs:193:17:193:18 | ! ... | test.rs:193:13:193:13 | IdentPat | | -| test.rs:193:18:193:18 | PathExpr | test.rs:193:17:193:18 | ! ... | | -| test.rs:194:9:194:9 | PathExpr | test.rs:192:43:195:5 | BlockExpr | | +| test.rs:193:9:193:19 | LetStmt | test.rs:193:18:193:18 | a | | +| test.rs:193:13:193:13 | d | test.rs:194:9:194:9 | d | match, no-match | +| test.rs:193:17:193:18 | ! ... | test.rs:193:13:193:13 | d | | +| test.rs:193:18:193:18 | a | test.rs:193:17:193:18 | ! ... | | +| test.rs:194:9:194:9 | d | test.rs:192:43:195:5 | BlockExpr | | | test.rs:197:5:203:5 | enter test_if_and_operator | test.rs:198:12:198:22 | ... && ... | | | test.rs:197:5:203:5 | exit test_if_and_operator (normal) | test.rs:197:5:203:5 | exit test_if_and_operator | | | test.rs:197:63:203:5 | BlockExpr | test.rs:197:5:203:5 | exit test_if_and_operator (normal) | | | test.rs:198:9:202:9 | IfExpr | test.rs:197:63:203:5 | BlockExpr | | -| test.rs:198:12:198:12 | PathExpr | test.rs:198:17:198:17 | PathExpr | true | -| test.rs:198:12:198:12 | PathExpr | test.rs:201:13:201:17 | false | false | -| test.rs:198:12:198:17 | ... && ... | test.rs:198:12:198:12 | PathExpr | | +| test.rs:198:12:198:12 | a | test.rs:198:17:198:17 | b | true | +| test.rs:198:12:198:12 | a | test.rs:201:13:201:17 | false | false | +| test.rs:198:12:198:17 | ... && ... | test.rs:198:12:198:12 | a | | | test.rs:198:12:198:22 | ... && ... | test.rs:198:12:198:17 | ... && ... | | -| test.rs:198:17:198:17 | PathExpr | test.rs:198:22:198:22 | PathExpr | true | -| test.rs:198:17:198:17 | PathExpr | test.rs:201:13:201:17 | false | false | -| test.rs:198:22:198:22 | PathExpr | test.rs:199:13:199:16 | true | true | -| test.rs:198:22:198:22 | PathExpr | test.rs:201:13:201:17 | false | false | +| test.rs:198:17:198:17 | b | test.rs:198:22:198:22 | c | true | +| test.rs:198:17:198:17 | b | test.rs:201:13:201:17 | false | false | +| test.rs:198:22:198:22 | c | test.rs:199:13:199:16 | true | true | +| test.rs:198:22:198:22 | c | test.rs:201:13:201:17 | false | false | | test.rs:198:24:200:9 | BlockExpr | test.rs:198:9:202:9 | IfExpr | | | test.rs:199:13:199:16 | true | test.rs:198:24:200:9 | BlockExpr | | | test.rs:200:16:202:9 | BlockExpr | test.rs:198:9:202:9 | IfExpr | | @@ -354,41 +354,41 @@ | test.rs:205:5:211:5 | exit test_if_or_operator (normal) | test.rs:205:5:211:5 | exit test_if_or_operator | | | test.rs:205:62:211:5 | BlockExpr | test.rs:205:5:211:5 | exit test_if_or_operator (normal) | | | test.rs:206:9:210:9 | IfExpr | test.rs:205:62:211:5 | BlockExpr | | -| test.rs:206:12:206:12 | PathExpr | test.rs:206:17:206:17 | PathExpr | false | -| test.rs:206:12:206:12 | PathExpr | test.rs:207:13:207:16 | true | true | -| test.rs:206:12:206:17 | ... \|\| ... | test.rs:206:12:206:12 | PathExpr | | +| test.rs:206:12:206:12 | a | test.rs:206:17:206:17 | b | false | +| test.rs:206:12:206:12 | a | test.rs:207:13:207:16 | true | true | +| test.rs:206:12:206:17 | ... \|\| ... | test.rs:206:12:206:12 | a | | | test.rs:206:12:206:22 | ... \|\| ... | test.rs:206:12:206:17 | ... \|\| ... | | -| test.rs:206:17:206:17 | PathExpr | test.rs:206:22:206:22 | PathExpr | false | -| test.rs:206:17:206:17 | PathExpr | test.rs:207:13:207:16 | true | true | -| test.rs:206:22:206:22 | PathExpr | test.rs:207:13:207:16 | true | true | -| test.rs:206:22:206:22 | PathExpr | test.rs:209:13:209:17 | false | false | +| test.rs:206:17:206:17 | b | test.rs:206:22:206:22 | c | false | +| test.rs:206:17:206:17 | b | test.rs:207:13:207:16 | true | true | +| test.rs:206:22:206:22 | c | test.rs:207:13:207:16 | true | true | +| test.rs:206:22:206:22 | c | test.rs:209:13:209:17 | false | false | | test.rs:206:24:208:9 | BlockExpr | test.rs:206:9:210:9 | IfExpr | | | test.rs:207:13:207:16 | true | test.rs:206:24:208:9 | BlockExpr | | | test.rs:208:16:210:9 | BlockExpr | test.rs:206:9:210:9 | IfExpr | | | test.rs:209:13:209:17 | false | test.rs:208:16:210:9 | BlockExpr | | -| test.rs:213:5:219:5 | enter test_if_not_operator | test.rs:214:13:214:13 | PathExpr | | +| test.rs:213:5:219:5 | enter test_if_not_operator | test.rs:214:13:214:13 | a | | | test.rs:213:5:219:5 | exit test_if_not_operator (normal) | test.rs:213:5:219:5 | exit test_if_not_operator | | | test.rs:213:46:219:5 | BlockExpr | test.rs:213:5:219:5 | exit test_if_not_operator (normal) | | | test.rs:214:9:218:9 | IfExpr | test.rs:213:46:219:5 | BlockExpr | | | test.rs:214:12:214:13 | ! ... | test.rs:215:13:215:16 | true | true | | test.rs:214:12:214:13 | ! ... | test.rs:217:13:217:17 | false | false | -| test.rs:214:13:214:13 | PathExpr | test.rs:214:12:214:13 | ! ... | false, true | +| test.rs:214:13:214:13 | a | test.rs:214:12:214:13 | ! ... | false, true | | test.rs:214:15:216:9 | BlockExpr | test.rs:214:9:218:9 | IfExpr | | | test.rs:215:13:215:16 | true | test.rs:214:15:216:9 | BlockExpr | | | test.rs:216:16:218:9 | BlockExpr | test.rs:214:9:218:9 | IfExpr | | | test.rs:217:13:217:17 | false | test.rs:216:16:218:9 | BlockExpr | | -| test.rs:222:1:228:1 | enter test_match | test.rs:223:11:223:21 | PathExpr | | +| test.rs:222:1:228:1 | enter test_match | test.rs:223:11:223:21 | maybe_digit | | | test.rs:222:1:228:1 | exit test_match (normal) | test.rs:222:1:228:1 | exit test_match | | | test.rs:222:48:228:1 | BlockExpr | test.rs:222:1:228:1 | exit test_match (normal) | | | test.rs:223:5:227:5 | MatchExpr | test.rs:222:48:228:1 | BlockExpr | | -| test.rs:223:11:223:21 | PathExpr | test.rs:224:9:224:23 | TupleStructPat | | -| test.rs:224:9:224:23 | TupleStructPat | test.rs:224:28:224:28 | PathExpr | match | +| test.rs:223:11:223:21 | maybe_digit | test.rs:224:9:224:23 | TupleStructPat | | +| test.rs:224:9:224:23 | TupleStructPat | test.rs:224:28:224:28 | x | match | | test.rs:224:9:224:23 | TupleStructPat | test.rs:225:9:225:23 | TupleStructPat | no-match | -| test.rs:224:28:224:28 | PathExpr | test.rs:224:32:224:33 | 10 | | +| test.rs:224:28:224:28 | x | test.rs:224:32:224:33 | 10 | | | test.rs:224:32:224:33 | 10 | test.rs:224:28:224:33 | ... < ... | | -| test.rs:225:9:225:23 | TupleStructPat | test.rs:225:28:225:28 | PathExpr | match | +| test.rs:225:9:225:23 | TupleStructPat | test.rs:225:28:225:28 | x | match | | test.rs:225:9:225:23 | TupleStructPat | test.rs:226:9:226:20 | PathPat | no-match | -| test.rs:225:28:225:28 | PathExpr | test.rs:223:5:227:5 | MatchExpr | | +| test.rs:225:28:225:28 | x | test.rs:223:5:227:5 | MatchExpr | | | test.rs:226:9:226:20 | PathPat | test.rs:226:25:226:25 | 5 | match | | test.rs:226:25:226:25 | 5 | test.rs:223:5:227:5 | MatchExpr | | | test.rs:231:5:236:5 | enter test_infinite_loop | test.rs:232:9:234:9 | ExprStmt | | @@ -398,12 +398,12 @@ | test.rs:238:5:241:5 | enter test_let_match | test.rs:239:9:239:49 | LetStmt | | | test.rs:238:5:241:5 | exit test_let_match (normal) | test.rs:238:5:241:5 | exit test_let_match | | | test.rs:238:39:241:5 | BlockExpr | test.rs:238:5:241:5 | exit test_let_match (normal) | | -| test.rs:239:9:239:49 | LetStmt | test.rs:239:23:239:23 | PathExpr | | +| test.rs:239:9:239:49 | LetStmt | test.rs:239:23:239:23 | a | | | test.rs:239:13:239:19 | TupleStructPat | test.rs:239:32:239:46 | "Expected some" | no-match | -| test.rs:239:13:239:19 | TupleStructPat | test.rs:240:9:240:9 | PathExpr | match | -| test.rs:239:23:239:23 | PathExpr | test.rs:239:13:239:19 | TupleStructPat | | +| test.rs:239:13:239:19 | TupleStructPat | test.rs:240:9:240:9 | n | match | +| test.rs:239:23:239:23 | a | test.rs:239:13:239:19 | TupleStructPat | | | test.rs:239:32:239:46 | "Expected some" | test.rs:239:30:239:48 | BlockExpr | | -| test.rs:240:9:240:9 | PathExpr | test.rs:238:39:241:5 | BlockExpr | | +| test.rs:240:9:240:9 | n | test.rs:238:39:241:5 | BlockExpr | | | test.rs:244:1:249:1 | enter dead_code | test.rs:245:5:247:5 | ExprStmt | | | test.rs:244:1:249:1 | exit dead_code (normal) | test.rs:244:1:249:1 | exit dead_code | | | test.rs:245:5:247:5 | ExprStmt | test.rs:245:9:245:12 | true | | @@ -416,8 +416,8 @@ | test.rs:251:1:264:1 | exit labelled_block (normal) | test.rs:251:1:264:1 | exit labelled_block | | | test.rs:251:28:264:1 | BlockExpr | test.rs:251:1:264:1 | exit labelled_block (normal) | | | test.rs:252:5:263:6 | LetStmt | test.rs:253:9:253:19 | ExprStmt | | -| test.rs:252:9:252:14 | IdentPat | test.rs:251:28:264:1 | BlockExpr | match, no-match | -| test.rs:252:18:263:5 | BlockExpr | test.rs:252:9:252:14 | IdentPat | | +| test.rs:252:9:252:14 | result | test.rs:251:28:264:1 | BlockExpr | match, no-match | +| test.rs:252:18:263:5 | BlockExpr | test.rs:252:9:252:14 | result | | | test.rs:253:9:253:16 | PathExpr | test.rs:253:9:253:18 | CallExpr | | | test.rs:253:9:253:18 | CallExpr | test.rs:254:9:256:9 | ExprStmt | | | test.rs:253:9:253:19 | ExprStmt | test.rs:253:9:253:16 | PathExpr | | diff --git a/rust/ql/test/library-tests/variables/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/library-tests/variables/CONSISTENCY/CfgConsistency.expected new file mode 100644 index 000000000000..5457cb7c9d96 --- /dev/null +++ b/rust/ql/test/library-tests/variables/CONSISTENCY/CfgConsistency.expected @@ -0,0 +1,5 @@ +deadEnd +| variables.rs:2:5:2:22 | ExprStmt | +| variables.rs:6:5:6:22 | ExprStmt | +| variables.rs:200:16:200:21 | ... > ... | +| variables.rs:310:5:310:42 | LetStmt | diff --git a/rust/ql/test/library-tests/variables/variables.expected b/rust/ql/test/library-tests/variables/variables.expected new file mode 100644 index 000000000000..ba563aeab6ef --- /dev/null +++ b/rust/ql/test/library-tests/variables/variables.expected @@ -0,0 +1,148 @@ +testFailures +failures +variable +| variables.rs:1:14:1:14 | s | +| variables.rs:5:14:5:14 | i | +| variables.rs:10:9:10:10 | x1 | +| variables.rs:15:13:15:14 | x2 | +| variables.rs:22:9:22:10 | x3 | +| variables.rs:24:9:24:10 | x3 | +| variables.rs:30:9:30:10 | x4 | +| variables.rs:33:13:33:14 | x4 | +| variables.rs:47:13:47:14 | a1 | +| variables.rs:48:13:48:14 | b1 | +| variables.rs:51:13:51:13 | x | +| variables.rs:52:13:52:13 | y | +| variables.rs:62:9:62:10 | p1 | +| variables.rs:64:12:64:13 | a2 | +| variables.rs:65:12:65:13 | b2 | +| variables.rs:72:9:72:10 | s1 | +| variables.rs:74:21:74:22 | s2 | +| variables.rs:81:14:81:15 | x5 | +| variables.rs:89:9:89:10 | x6 | +| variables.rs:90:9:90:10 | y1 | +| variables.rs:94:14:94:15 | y1 | +| variables.rs:99:9:99:12 | None | +| variables.rs:106:9:106:15 | numbers | +| variables.rs:110:13:110:17 | first | +| variables.rs:111:13:111:17 | third | +| variables.rs:112:13:112:17 | fifth | +| variables.rs:122:13:122:17 | first | +| variables.rs:124:13:124:16 | last | +| variables.rs:133:9:133:10 | p2 | +| variables.rs:137:16:137:17 | x7 | +| variables.rs:147:9:147:11 | msg | +| variables.rs:151:17:151:27 | id_variable | +| variables.rs:156:26:156:27 | id | +| variables.rs:167:9:167:14 | either | +| variables.rs:169:9:169:44 | a3 | +| variables.rs:181:9:181:10 | tv | +| variables.rs:183:9:183:81 | a4 | +| variables.rs:187:9:187:83 | a5 | +| variables.rs:191:9:191:83 | a6 | +| variables.rs:197:9:197:14 | either | +| variables.rs:199:9:199:44 | a7 | +| variables.rs:207:9:207:14 | either | +| variables.rs:210:13:210:13 | e | +| variables.rs:211:14:211:51 | a11 | +| variables.rs:214:33:214:35 | a12 | +| variables.rs:231:9:231:10 | fv | +| variables.rs:233:9:233:109 | a13 | +| variables.rs:239:5:239:6 | a8 | +| variables.rs:241:9:241:10 | b3 | +| variables.rs:242:9:242:10 | c1 | +| variables.rs:250:6:250:41 | a9 | +| variables.rs:257:13:257:15 | a10 | +| variables.rs:258:13:258:14 | b4 | +| variables.rs:259:13:259:14 | c2 | +| variables.rs:280:13:280:15 | a10 | +| variables.rs:281:13:281:14 | b4 | +| variables.rs:293:9:293:23 | example_closure | +| variables.rs:294:10:294:10 | x | +| variables.rs:296:9:296:10 | n1 | +| variables.rs:301:9:301:26 | immutable_variable | +| variables.rs:302:10:302:10 | x | +| variables.rs:304:9:304:10 | n2 | +| variables.rs:310:9:310:9 | v | +| variables.rs:312:9:312:12 | text | +variableAccess +| variables.rs:11:15:11:16 | x1 | variables.rs:10:9:10:10 | x1 | +| variables.rs:16:15:16:16 | x2 | variables.rs:15:13:15:14 | x2 | +| variables.rs:17:5:17:6 | x2 | variables.rs:15:13:15:14 | x2 | +| variables.rs:18:15:18:16 | x2 | variables.rs:15:13:15:14 | x2 | +| variables.rs:23:15:23:16 | x3 | variables.rs:22:9:22:10 | x3 | +| variables.rs:25:9:25:10 | x3 | variables.rs:22:9:22:10 | x3 | +| variables.rs:26:15:26:16 | x3 | variables.rs:24:9:24:10 | x3 | +| variables.rs:31:15:31:16 | x4 | variables.rs:30:9:30:10 | x4 | +| variables.rs:34:19:34:20 | x4 | variables.rs:33:13:33:14 | x4 | +| variables.rs:36:15:36:16 | x4 | variables.rs:30:9:30:10 | x4 | +| variables.rs:55:15:55:16 | a1 | variables.rs:47:13:47:14 | a1 | +| variables.rs:56:15:56:16 | b1 | variables.rs:48:13:48:14 | b1 | +| variables.rs:57:15:57:15 | x | variables.rs:51:13:51:13 | x | +| variables.rs:58:15:58:15 | y | variables.rs:52:13:52:13 | y | +| variables.rs:66:9:66:10 | p1 | variables.rs:62:9:62:10 | p1 | +| variables.rs:67:15:67:16 | a2 | variables.rs:64:12:64:13 | a2 | +| variables.rs:68:15:68:16 | b2 | variables.rs:65:12:65:13 | b2 | +| variables.rs:75:11:75:12 | s1 | variables.rs:72:9:72:10 | s1 | +| variables.rs:76:19:76:20 | s2 | variables.rs:74:21:74:22 | s2 | +| variables.rs:85:15:85:16 | x5 | variables.rs:81:14:81:15 | x5 | +| variables.rs:92:11:92:12 | x6 | variables.rs:89:9:89:10 | x6 | +| variables.rs:97:23:97:24 | y1 | variables.rs:94:14:94:15 | y1 | +| variables.rs:102:15:102:16 | y1 | variables.rs:90:9:90:10 | y1 | +| variables.rs:108:11:108:17 | numbers | variables.rs:106:9:106:15 | numbers | +| variables.rs:114:23:114:27 | first | variables.rs:110:13:110:17 | first | +| variables.rs:115:23:115:27 | third | variables.rs:111:13:111:17 | third | +| variables.rs:116:23:116:27 | fifth | variables.rs:112:13:112:17 | fifth | +| variables.rs:120:11:120:17 | numbers | variables.rs:106:9:106:15 | numbers | +| variables.rs:126:23:126:27 | first | variables.rs:122:13:122:17 | first | +| variables.rs:127:23:127:26 | last | variables.rs:124:13:124:16 | last | +| variables.rs:135:11:135:12 | p2 | variables.rs:133:9:133:10 | p2 | +| variables.rs:138:24:138:25 | x7 | variables.rs:137:16:137:17 | x7 | +| variables.rs:149:11:149:13 | msg | variables.rs:147:9:147:11 | msg | +| variables.rs:152:24:152:34 | id_variable | variables.rs:151:17:151:27 | id_variable | +| variables.rs:157:23:157:24 | id | variables.rs:156:26:156:27 | id | +| variables.rs:168:11:168:16 | either | variables.rs:167:9:167:14 | either | +| variables.rs:170:26:170:27 | a3 | variables.rs:169:9:169:44 | a3 | +| variables.rs:182:11:182:12 | tv | variables.rs:181:9:181:10 | tv | +| variables.rs:184:26:184:27 | a4 | variables.rs:183:9:183:81 | a4 | +| variables.rs:186:11:186:12 | tv | variables.rs:181:9:181:10 | tv | +| variables.rs:188:26:188:27 | a5 | variables.rs:187:9:187:83 | a5 | +| variables.rs:190:11:190:12 | tv | variables.rs:181:9:181:10 | tv | +| variables.rs:192:26:192:27 | a6 | variables.rs:191:9:191:83 | a6 | +| variables.rs:198:11:198:16 | either | variables.rs:197:9:197:14 | either | +| variables.rs:200:16:200:17 | a7 | variables.rs:199:9:199:44 | a7 | +| variables.rs:201:26:201:27 | a7 | variables.rs:199:9:199:44 | a7 | +| variables.rs:209:11:209:16 | either | variables.rs:207:9:207:14 | either | +| variables.rs:213:23:213:25 | a11 | variables.rs:211:14:211:51 | a11 | +| variables.rs:215:15:215:15 | e | variables.rs:210:13:210:13 | e | +| variables.rs:216:28:216:30 | a12 | variables.rs:214:33:214:35 | a12 | +| variables.rs:232:11:232:12 | fv | variables.rs:231:9:231:10 | fv | +| variables.rs:234:26:234:28 | a13 | variables.rs:233:9:233:109 | a13 | +| variables.rs:244:15:244:16 | a8 | variables.rs:239:5:239:6 | a8 | +| variables.rs:245:15:245:16 | b3 | variables.rs:241:9:241:10 | b3 | +| variables.rs:246:15:246:16 | c1 | variables.rs:242:9:242:10 | c1 | +| variables.rs:252:15:252:16 | a9 | variables.rs:250:6:250:41 | a9 | +| variables.rs:261:15:261:17 | a10 | variables.rs:257:13:257:15 | a10 | +| variables.rs:262:15:262:16 | b4 | variables.rs:258:13:258:14 | b4 | +| variables.rs:263:15:263:16 | c2 | variables.rs:259:13:259:14 | c2 | +| variables.rs:266:9:266:10 | c2 | variables.rs:259:13:259:14 | c2 | +| variables.rs:267:9:267:10 | b4 | variables.rs:258:13:258:14 | b4 | +| variables.rs:268:9:268:11 | a10 | variables.rs:257:13:257:15 | a10 | +| variables.rs:270:9:270:11 | a10 | variables.rs:257:13:257:15 | a10 | +| variables.rs:271:9:271:10 | b4 | variables.rs:258:13:258:14 | b4 | +| variables.rs:272:9:272:10 | c2 | variables.rs:259:13:259:14 | c2 | +| variables.rs:274:15:274:17 | a10 | variables.rs:257:13:257:15 | a10 | +| variables.rs:275:15:275:16 | b4 | variables.rs:258:13:258:14 | b4 | +| variables.rs:276:15:276:16 | c2 | variables.rs:259:13:259:14 | c2 | +| variables.rs:283:23:283:25 | a10 | variables.rs:280:13:280:15 | a10 | +| variables.rs:284:23:284:24 | b4 | variables.rs:281:13:281:14 | b4 | +| variables.rs:288:15:288:17 | a10 | variables.rs:257:13:257:15 | a10 | +| variables.rs:289:15:289:16 | b4 | variables.rs:258:13:258:14 | b4 | +| variables.rs:295:9:295:9 | x | variables.rs:294:10:294:10 | x | +| variables.rs:297:9:297:23 | example_closure | variables.rs:293:9:293:23 | example_closure | +| variables.rs:298:15:298:16 | n1 | variables.rs:296:9:296:10 | n1 | +| variables.rs:303:9:303:9 | x | variables.rs:302:10:302:10 | x | +| variables.rs:305:9:305:26 | immutable_variable | variables.rs:301:9:301:26 | immutable_variable | +| variables.rs:306:15:306:16 | n2 | variables.rs:304:9:304:10 | n2 | +| variables.rs:313:12:313:12 | v | variables.rs:310:9:310:9 | v | +| variables.rs:314:19:314:22 | text | variables.rs:312:9:312:12 | text | diff --git a/rust/ql/test/library-tests/variables/variables.ql b/rust/ql/test/library-tests/variables/variables.ql new file mode 100644 index 000000000000..b96f6ceabcae --- /dev/null +++ b/rust/ql/test/library-tests/variables/variables.ql @@ -0,0 +1,41 @@ +import rust +import utils.InlineExpectationsTest + +query predicate variable(Variable v) { any() } + +query predicate variableAccess(VariableAccess va, Variable v) { v = va.getVariable() } + +module VariableAccessTest implements TestSig { + string getARelevantTag() { result = "access" } + + private predicate declAt(Variable v, string filepath, int line) { + v.getLocation().hasLocationInfo(filepath, _, _, line, _) + } + + private predicate commmentAt(string text, string filepath, int line) { + exists(Comment c | + c.getLocation().hasLocationInfo(filepath, line, _, _, _) and + c.getCommentText() = text + ) + } + + private predicate decl(Variable v, string value) { + exists(string filepath, int line | declAt(v, filepath, line) | + commmentAt(value, filepath, line) + or + not commmentAt(_, filepath, line) and + value = v.getName() + ) + } + + predicate hasActualResult(Location location, string element, string tag, string value) { + exists(VariableAccess va | + location = va.getLocation() and + element = va.toString() and + tag = "access" and + decl(va.getVariable(), value) + ) + } +} + +import MakeTest diff --git a/rust/ql/test/library-tests/variables/variables.rs b/rust/ql/test/library-tests/variables/variables.rs new file mode 100644 index 000000000000..8a0e83c9eff7 --- /dev/null +++ b/rust/ql/test/library-tests/variables/variables.rs @@ -0,0 +1,341 @@ +fn print_str(s: &str) { + println!("{}", s); +} + +fn print_i64(i: i64) { + println!("{}", i); +} + +fn immutable_variable() { + let x1 = "a"; // x1 + print_str(x1); // $ access=x1 +} + +fn mutable_variable() { + let mut x2 = 4; // x2 + print_i64(x2); // $ access=x2 + x2 = 5; // $ access=x2 + print_i64(x2); // $ access=x2 +} + +fn variable_shadow1() { + let x3 = 1; // x3_1 + print_i64(x3); // $ access=x3_1 + let x3 = // x3_2 + x3 + 1; // $ access=x3_1 + print_i64(x3); // $ access=x3_2 +} + +fn variable_shadow2() { + let x4 = "a"; // x4_1 + print_str(x4); // $ access=x4_1 + { + let x4 = "b"; // x4_2 + print_str(x4); // $ access=x4_2 + } + print_str(x4); // $ access=x4_1 +} + +struct Point<'a> { + x: &'a str, + y: &'a str, +} + +fn let_pattern1() { + let ( + ( + a1, // a1 + b1, // b1 + ), + Point { + x, // x + y, // y + }, + ) = (("a", "b"), Point { x: "x", y: "y" }); + print_str(a1); // $ access=a1 + print_str(b1); // $ access=b1 + print_str(x); // $ access=x + print_str(y); // $ access=y +} + +fn let_pattern2() { + let p1 = Point { x: "a", y: "b" }; // p1 + let Point { + x: a2, // a2 + y: b2, // b2 + } = p1; // $ access=p1 + print_str(a2); // $ access=a2 + print_str(b2); // $ access=b2 +} + +fn let_pattern3() { + let s1 = Some(String::from("Hello!")); // s1 + + if let Some(ref s2) // s2 + = s1 { // $ access=s1 + print_str(s2); // $ access=s2 + } +} + +fn let_pattern4() { + let Some(x5): Option<&str> = Some("x5") else { + // x5 + todo!() + }; + print_str(x5); // $ access=x5 +} + +fn match_pattern1() { + let x6 = Some(5); // x6 + let y1 = 10; // y1_1 + + match x6 { // $ access=x6 + Some(50) => print_str("Got 50"), + Some(y1) // y1_2 + => + { + print_i64(y1)// $ access=y1_2 + } + None => print_str("NONE"), + } + + print_i64(y1); // $ access=y1_1 +} + +fn match_pattern2() { + let numbers = (2, 4, 8, 16, 32); // numbers + + match numbers { // $ access=numbers + ( + first, _, // first + third, _, // third + fifth // fifth + ) => { + print_i64(first); // $ access=first + print_i64(third); // $ access=third + print_i64(fifth); // $ access=fifth + } + } + + match numbers { // $ access=numbers + ( + first, // first + .., + last // last + ) => { + print_i64(first); // $ access=first + print_i64(last); // $ access=last + } + } +} + +fn match_pattern3() { + let p2 = Point { x: "x", y: "y" }; // p2 + + match p2 { // $ access=p2 + Point { + x: x7, .. // x7 + } => print_str(x7), // $ access=x7 + } +} + +enum Message { + Hello { id: i64 }, +} + +fn match_pattern4() { + let msg = Message::Hello { id: 0 }; // msg + + match msg { // $ access=msg + Message::Hello { + id: id_variable @ 3..=7, // id_variable + } => print_i64(id_variable), // $ access=id_variable + Message::Hello { id: 10..=12 } => { + println!("Found an id in another range") + } + Message::Hello { id } => // id + print_i64(id), // $ access=id + } +} + +enum Either { + Left(i64), + Right(i64), +} + +fn match_pattern5() { + let either = Either::Left(32); // either + match either { // $ access=either + Either::Left(a3) | Either::Right(a3) // a3 + => print_i64(a3), // $ access=a3 + } +} + +enum ThreeValued { + First(i64), + Second(i64), + Third(i64), +} + +fn match_pattern6() { + let tv = ThreeValued::Second(62); // tv + match tv { // $ access=tv + ThreeValued::First(a4) | ThreeValued::Second(a4) | ThreeValued::Third(a4) // a4 + => print_i64(a4), // $ access=a4 + } + match tv { // $ access=tv + (ThreeValued::First(a5) | ThreeValued::Second(a5)) | ThreeValued::Third(a5) // a5 + => print_i64(a5), // $ access=a5 + } + match tv { // $ access=tv + ThreeValued::First(a6) | (ThreeValued::Second(a6) | ThreeValued::Third(a6)) // a6 + => print_i64(a6), // $ access=a6 + } +} + +fn match_pattern7() { + let either = Either::Left(32); // either + match either { // $ access=either + Either::Left(a7) | Either::Right(a7) // a7 + if a7 > 0 // $ access=a7 + => print_i64(a7), // $ access=a7 + _ => (), + } +} + +fn match_pattern8() { + let either = Either::Left(32); // either + + match either { // $ access=either + ref e @ // e + (Either::Left(a11) | Either::Right(a11)) // a11 + => { + print_i64(a11); // $ access=a11 + if let Either::Left(a12) // a12 + = e { // $ access=e + print_i64(*a12); // $ access=a12 + } + } + _ => (), + } +} + +enum FourValued { + First(i64), + Second(i64), + Third(i64), + Fourth(i64), +} + +fn match_pattern9() { + let fv = FourValued::Second(62); // tv + match fv { // $ access=tv + FourValued::First(a13) | (FourValued::Second(a13) | FourValued::Third(a13)) | FourValued::Fourth(a13) // a13 + => print_i64(a13), // $ access=a13 + } +} + +fn param_pattern1( + a8: &str, // a8 + ( + b3, // b3 + c1, // c1 + ): (&str, &str)) -> () { + print_str(a8); // $ access=a8 + print_str(b3); // $ access=b3 + print_str(c1); // $ access=c1 +} + +fn param_pattern2( + (Either::Left(a9) | Either::Right(a9)): Either // a9 +) -> () { + print_i64(a9); // $ access=a9 +} + +fn destruct_assignment() { + let ( + mut a10, // a10 + mut b4, // b4 + mut c2 // c2 + ) = (1, 2, 3); + print_i64(a10); // $ access=a10 + print_i64(b4); // $ access=b4 + print_i64(c2); // $ access=c2 + + ( + c2, // $ access=c2 + b4, // $ access=b4 + a10 // $ access=a10 + ) = ( + a10, // $ access=a10 + b4, // $ access=b4 + c2 // $ access=c2 + ); + print_i64(a10); // $ access=a10 + print_i64(b4); // $ access=b4 + print_i64(c2); // $ access=c2 + + match (4, 5) { + ( + a10, // a10_2 + b4 // b4 + ) => { + print_i64(a10); // $ access=a10_2 + print_i64(b4); // $ access=b4 + } + } + + print_i64(a10); // $ access=a10 + print_i64(b4); // $ access=b4 +} + +fn closure_variable() { + let example_closure = // example_closure + |x: i64| // x_1 + x; // $ access=x_1 + let n1 = // n1 + example_closure(5); // $ access=example_closure + print_i64(n1); // $ access=n1 + + immutable_variable(); + let immutable_variable = + |x: i64| // x_2 + x; // $ access=x_2 + let n2 = // n2 + immutable_variable(6); // $ access=immutable_variable + print_i64(n2); // $ access=n2 +} + +fn for_variable() { + let v = &["apples", "cake", "coffee"]; // v + + for text // text + in v { // $ access=v + print_str(text); // $ access=text + } +} + +fn main() { + immutable_variable(); + mutable_variable(); + variable_shadow1(); + variable_shadow2(); + let_pattern1(); + let_pattern2(); + let_pattern3(); + let_pattern4(); + match_pattern1(); + match_pattern2(); + match_pattern3(); + match_pattern4(); + match_pattern5(); + match_pattern6(); + match_pattern7(); + match_pattern8(); + match_pattern9(); + param_pattern1("a", ("b", "c")); + param_pattern2(Either::Left(45)); + destruct_assignment(); + closure_variable(); + for_variable(); +} diff --git a/rust/ql/test/utils/InlineExpectationsTest.qll b/rust/ql/test/utils/InlineExpectationsTest.qll new file mode 100644 index 000000000000..840e04ccbe01 --- /dev/null +++ b/rust/ql/test/utils/InlineExpectationsTest.qll @@ -0,0 +1,8 @@ +/** + * Inline expectation tests for Rust. + * See `shared/util/codeql/util/test/InlineExpectationsTest.qll` + */ + +private import codeql.util.test.InlineExpectationsTest +private import internal.InlineExpectationsTestImpl +import Make diff --git a/rust/ql/test/utils/internal/InlineExpectationsTestImpl.qll b/rust/ql/test/utils/internal/InlineExpectationsTestImpl.qll new file mode 100644 index 000000000000..2e851f529512 --- /dev/null +++ b/rust/ql/test/utils/internal/InlineExpectationsTestImpl.qll @@ -0,0 +1,12 @@ +private import rust as R +private import R +private import codeql.util.test.InlineExpectationsTest + +module Impl implements InlineExpectationsTestSig { + class ExpectationComment extends R::Comment { + /** Gets the contents of the given comment, _without_ the preceding comment marker (`//`). */ + string getContents() { result = this.getCommentText() } + } + + class Location = R::Location; +}