diff --git a/rust/ql/lib/codeql/rust/controlflow/internal/Completion.qll b/rust/ql/lib/codeql/rust/controlflow/internal/Completion.qll index 088866f7ea92..99b36e10c847 100644 --- a/rust/ql/lib/codeql/rust/controlflow/internal/Completion.qll +++ b/rust/ql/lib/codeql/rust/controlflow/internal/Completion.qll @@ -6,6 +6,14 @@ private import SuccessorType private newtype TCompletion = TSimpleCompletion() or TBooleanCompletion(Boolean b) or + TMatchCompletion(Boolean isMatch) or + TLoopCompletion(TLoopJumpType kind, TLabelType label) { + label = TNoLabel() + or + kind = TBreakJump() and label = TLabel(any(BreakExpr b).getLifetime().getText()) + or + kind = TContinueJump() and label = TLabel(any(ContinueExpr b).getLifetime().getText()) + } or TReturnCompletion() /** A completion of a statement or an expression. */ @@ -51,6 +59,10 @@ abstract class ConditionalCompletion extends NormalCompletion { /** Gets the Boolean value of this conditional completion. */ final boolean getValue() { result = value } + final predicate succeeded() { value = true } + + final predicate failed() { value = false } + /** Gets the dual completion. */ abstract ConditionalCompletion getDual(); } @@ -62,7 +74,34 @@ abstract class ConditionalCompletion extends NormalCompletion { class BooleanCompletion extends ConditionalCompletion, TBooleanCompletion { BooleanCompletion() { this = TBooleanCompletion(value) } - override predicate isValidForSpecific(AstNode e) { e = any(IfExpr c).getCondition() } + override predicate isValidForSpecific(AstNode e) { + e = any(IfExpr c).getCondition() + or + any(MatchArm arm).getGuard() = e + or + exists(BinaryExpr expr | + expr.getOperatorName() = ["&&", "||"] and + e = expr.getLhs() + ) + or + exists(Expr parent | this.isValidForSpecific(parent) | + parent = + any(PrefixExpr expr | + expr.getOperatorName() = "!" and + e = expr.getExpr() + ) + or + parent = + any(BinaryExpr expr | + expr.getOperatorName() = ["&&", "||"] and + e = expr.getRhs() + ) + or + parent = any(IfExpr ie | e = [ie.getThen(), ie.getElse()]) + or + parent = any(BlockExpr be | e = be.getStmtList().getTailExpr()) + ) + } /** Gets the dual Boolean completion. */ override BooleanCompletion getDual() { result = TBooleanCompletion(value.booleanNot()) } @@ -72,6 +111,63 @@ class BooleanCompletion extends ConditionalCompletion, TBooleanCompletion { override string toString() { result = "boolean(" + value + ")" } } +/** + * A completion that represents the result of a pattern match. + */ +class MatchCompletion extends TMatchCompletion, ConditionalCompletion { + MatchCompletion() { this = TMatchCompletion(value) } + + override predicate isValidForSpecific(AstNode e) { e instanceof Pat } + + override MatchSuccessor getAMatchingSuccessorType() { result.getValue() = value } + + /** Gets the dual match completion. */ + override MatchCompletion getDual() { result = TMatchCompletion(value.booleanNot()) } + + override string toString() { result = "match(" + value + ")" } +} + +/** + * A completion that represents a break or a continue. + */ +class LoopJumpCompletion extends TLoopCompletion, Completion { + override LoopJumpSuccessor getAMatchingSuccessorType() { + result = TLoopSuccessor(this.getKind(), this.getLabelType()) + } + + final TLoopJumpType getKind() { this = TLoopCompletion(result, _) } + + final TLabelType getLabelType() { this = TLoopCompletion(_, result) } + + final predicate hasLabel() { this.getLabelType() = TLabel(_) } + + final string getLabelName() { TLabel(result) = this.getLabelType() } + + final predicate isContinue() { this.getKind() = TContinueJump() } + + final predicate isBreak() { this.getKind() = TBreakJump() } + + override predicate isValidForSpecific(AstNode e) { + this.isBreak() and + e instanceof BreakExpr and + ( + not e.(BreakExpr).hasLifetime() and not this.hasLabel() + or + e.(BreakExpr).getLifetime().getText() = this.getLabelName() + ) + or + this.isContinue() and + e instanceof ContinueExpr and + ( + not e.(ContinueExpr).hasLifetime() and not this.hasLabel() + or + e.(ContinueExpr).getLifetime().getText() = this.getLabelName() + ) + } + + override string toString() { result = this.getAMatchingSuccessorType().toString() } +} + /** * A completion that represents a return. */ diff --git a/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll b/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll index 7b9d89dddf2a..bde6ecdc6631 100644 --- a/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll +++ b/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll @@ -49,25 +49,99 @@ module CfgInput implements InputSig { int maxSplits() { result = 0 } /** Holds if `first` is first executed when entering `scope`. */ - predicate scopeFirst(CfgScope scope, AstNode first) { - scope.(CfgImpl::ControlFlowTree).first(first) - } + predicate scopeFirst(CfgScope scope, AstNode first) { scope.scopeFirst(first) } /** Holds if `scope` is exited when `last` finishes with completion `c`. */ - predicate scopeLast(CfgScope scope, AstNode last, Completion c) { - scope.(CfgImpl::ControlFlowTree).last(last, c) - } + predicate scopeLast(CfgScope scope, AstNode last, Completion c) { scope.scopeLast(last, c) } } -module CfgImpl = Make; +private module CfgImpl = Make; import CfgImpl -class FunctionTree extends StandardPostOrderTree instanceof Function { - override ControlFlowTree getChildNode(int i) { i = 0 and result = super.getBody() } +/** Holds if `p` is a trivial pattern that is always guaranteed to match. */ +predicate trivialPat(Pat p) { p instanceof WildcardPat or p instanceof IdentPat } + +class AsmExprTree extends LeafTree instanceof AsmExpr { } + +class AwaitExprTree extends StandardPostOrderTree instanceof AwaitExpr { + override ControlFlowTree getChildNode(int i) { i = 0 and result = super.getExpr() } +} + +// NOTE: `become` is a reserved but unused keyword. +class BecomeExprTree extends StandardPostOrderTree instanceof BecomeExpr { + override ControlFlowTree getChildNode(int i) { i = 0 and result = super.getExpr() } +} + +class BinaryOpExprTree extends StandardPostOrderTree instanceof BinaryExpr { + BinaryOpExprTree() { super.getOperatorName() != "&&" and super.getOperatorName() != "||" } + + override ControlFlowTree getChildNode(int i) { + i = 0 and result = super.getLhs() + or + i = 1 and result = super.getRhs() + } +} + +class LogicalOrBinaryOpExprTree extends PreOrderTree instanceof BinaryExpr { + LogicalOrBinaryOpExprTree() { super.getOperatorName() = "||" } + + final override predicate propagatesAbnormal(AstNode child) { + child = [super.getRhs(), super.getLhs()] + } + + override predicate succ(AstNode pred, AstNode succ, Completion c) { + // Edge to the first node in the lhs + pred = this and + first(super.getLhs(), succ) and + completionIsSimple(c) + or + // Edge from the last node in the lhs to the first node in the rhs + last(super.getLhs(), pred, c) and + first(super.getRhs(), succ) and + c.(BooleanCompletion).failed() + } + + override predicate last(AstNode node, Completion c) { + // Lhs. as the last node + last(super.getLhs(), node, c) and + c.(BooleanCompletion).succeeded() + or + // Rhs. as the last node + last(super.getRhs(), node, c) + } } -class BlockExprTree extends StandardPostOrderTree instanceof BlockExpr { +class LogicalAndBinaryOpExprTree extends PreOrderTree instanceof BinaryExpr { + LogicalAndBinaryOpExprTree() { super.getOperatorName() = "&&" } + + final override predicate propagatesAbnormal(AstNode child) { + child = [super.getRhs(), super.getLhs()] + } + + override predicate succ(AstNode pred, AstNode succ, Completion c) { + // Edge to the first node in the lhs + pred = this and + first(super.getLhs(), succ) and + completionIsSimple(c) + or + // Edge from the last node in the lhs to the first node in the rhs + last(super.getLhs(), pred, c) and + first(super.getRhs(), succ) and + c.(BooleanCompletion).succeeded() + } + + override predicate last(AstNode node, Completion c) { + // Lhs. as the last node + last(super.getLhs(), node, c) and + c.(BooleanCompletion).failed() + or + // Rhs. as the last node + last(super.getRhs(), node, c) + } +} + +class BlockExprBaseTree extends StandardPostOrderTree instanceof BlockExpr { override ControlFlowTree getChildNode(int i) { result = super.getStmtList().getStatement(i) or @@ -77,18 +151,46 @@ class BlockExprTree extends StandardPostOrderTree instanceof BlockExpr { } } -class CallExprTree extends StandardPostOrderTree instanceof CallExpr { - override ControlFlowTree getChildNode(int i) { result = super.getArgList().getArg(i) } +class BreakExprTree extends PostOrderTree instanceof BreakExpr { + override predicate propagatesAbnormal(AstNode child) { child = super.getExpr() } + + override predicate first(AstNode node) { + first(super.getExpr(), node) + or + not super.hasExpr() and node = this + } + + override predicate succ(AstNode pred, AstNode succ, Completion c) { + last(super.getExpr(), pred, c) and succ = this + } } -class BinaryOpExprTree extends StandardPostOrderTree instanceof BinaryExpr { +class CallExprTree extends StandardPostOrderTree instanceof CallExpr { override ControlFlowTree getChildNode(int i) { - i = 0 and result = super.getLhs() + i = 0 and result = super.getExpr() or - i = 1 and result = super.getRhs() + result = super.getArgList().getArg(i - 1) } } +class CastExprTree extends StandardPostOrderTree instanceof CastExpr { + override ControlFlowTree getChildNode(int i) { i = 0 and result = super.getExpr() } +} + +class ClosureExprTree extends LeafTree instanceof ClosureExpr { } + +class ContinueExprTree extends LeafTree instanceof ContinueExpr { } + +class ExprStmtTree extends StandardPreOrderTree instanceof ExprStmt { + override ControlFlowTree getChildNode(int i) { i = 0 and result = super.getExpr() } +} + +class FieldExprTree extends StandardPostOrderTree instanceof FieldExpr { + override ControlFlowTree getChildNode(int i) { i = 0 and result = super.getExpr() } +} + +class FunctionTree extends LeafTree instanceof Function { } + class IfExprTree extends PostOrderTree instanceof IfExpr { override predicate first(AstNode node) { first(super.getCondition(), node) } @@ -96,13 +198,21 @@ class IfExprTree extends PostOrderTree instanceof IfExpr { child = [super.getCondition(), super.getThen(), super.getElse()] } + ConditionalCompletion conditionCompletion(Completion c) { + if super.getCondition() instanceof LetExpr + then result = c.(MatchCompletion) + else result = c.(BooleanCompletion) + } + override predicate succ(AstNode pred, AstNode succ, Completion c) { - // Edges from the condition to each branch + // Edges from the condition to the branches last(super.getCondition(), pred, c) and ( - first(super.getThen(), succ) and c.(BooleanCompletion).getValue() = true + first(super.getThen(), succ) and this.conditionCompletion(c).succeeded() + or + first(super.getElse(), succ) and this.conditionCompletion(c).failed() or - first(super.getElse(), succ) and c.(BooleanCompletion).getValue() = false + not super.hasElse() and succ = this and this.conditionCompletion(c).failed() ) or // An edge from the then branch to the last node @@ -117,10 +227,221 @@ class IfExprTree extends PostOrderTree instanceof IfExpr { } } -class LetExprTree extends StandardPostOrderTree instanceof LetExpr { - override ControlFlowTree getChildNode(int i) { i = 0 and result = super.getExpr() } +class IndexExprTree extends StandardPostOrderTree instanceof IndexExpr { + override ControlFlowTree getChildNode(int i) { + i = 0 and result = super.getBase() + or + i = 1 and result = super.getIndex() + } +} + +// `LetExpr` is a pre-order tree such that the pattern itself ends up +// dominating successors in the graph in the same way that patterns do in +// `match` expressions. +class LetExprTree extends StandardPreOrderTree instanceof LetExpr { + override ControlFlowTree getChildNode(int i) { i = 0 and result = super.getPat() } +} + +// We handle `let` statements with trivial patterns separately as they don't +// lead to non-standard control flow. For instance, in `let a = ...` it is not +// interesing to create match edges as it would carry no information. +class LetStmtTreeTrivialPat extends StandardPreOrderTree instanceof LetStmt { + LetStmtTreeTrivialPat() { trivialPat(super.getPat()) } + + override ControlFlowTree getChildNode(int i) { + i = 0 and result = super.getInitializer() + or + i = 1 and result = super.getPat() + } +} + +// `let` statements with interesting patterns that we want to be reflected in +// the CFG. +class LetStmtTree extends PreOrderTree instanceof LetStmt { + LetStmtTree() { not trivialPat(super.getPat()) } + + final override predicate propagatesAbnormal(AstNode child) { + child = [super.getInitializer(), super.getLetElse().getBlockExpr()] + } + + override predicate succ(AstNode pred, AstNode succ, Completion c) { + // Edge to start of initializer. + pred = this and first(super.getInitializer(), succ) and completionIsSimple(c) + or + // Edge from end of initializer to pattern. + last(super.getInitializer(), pred, c) and first(super.getPat(), succ) + or + // Edge from failed pattern to `else` branch. + last(super.getPat(), pred, c) and + first(super.getLetElse().getBlockExpr(), succ) and + c.(MatchCompletion).failed() + } + + override predicate last(AstNode node, Completion c) { + // Edge out of a successfully matched pattern. + last(super.getPat(), node, c) and c.(MatchCompletion).succeeded() + // NOTE: No edge out of the `else` branch as that is guaranteed to diverge. + } } class LiteralExprTree extends LeafTree instanceof LiteralExpr { } +class LoopExprTree extends PostOrderTree instanceof LoopExpr { + override predicate propagatesAbnormal(AstNode child) { none() } + + override predicate first(AstNode node) { first(super.getLoopBody(), node) } + + /** Whether this `LoopExpr` captures the `c` completion. */ + private predicate capturesLoopJumpCompletion(LoopJumpCompletion c) { + not c.hasLabel() + or + c.getLabelName() = super.getLabel().getLifetime().getText() + } + + override predicate succ(AstNode pred, AstNode succ, Completion c) { + // Edge back to the start for final expression and continue expressions + last(super.getLoopBody(), pred, c) and + ( + completionIsNormal(c) + or + c.(LoopJumpCompletion).isContinue() and this.capturesLoopJumpCompletion(c) + ) and + this.first(succ) + or + // Edge for exiting the loop with a break expressions + last(super.getLoopBody(), pred, c) and + c.(LoopJumpCompletion).isBreak() and + this.capturesLoopJumpCompletion(c) and + succ = this + } + + override predicate last(AstNode last, Completion c) { + super.last(last, c) + or + // Any abnormal completions that this loop does not capture should propagate + last(super.getLoopBody(), last, c) and + not completionIsNormal(c) and + not this.capturesLoopJumpCompletion(c) + } +} + +class MatchArmTree extends ControlFlowTree instanceof MatchArm { + override predicate propagatesAbnormal(AstNode child) { child = super.getExpr() } + + override predicate first(AstNode node) { node = super.getPat() } + + override predicate succ(AstNode pred, AstNode succ, Completion c) { + // Edge from pattern to guard/arm if match succeeds. + pred = super.getPat() and + c.(MatchCompletion).succeeded() and + ( + first(super.getGuard().getCondition(), succ) + or + not super.hasGuard() and first(super.getExpr(), succ) + ) + or + // Edge from guard to arm if the guard succeeds. + last(super.getGuard().getCondition(), pred, c) and + first(super.getExpr(), succ) and + c.(BooleanCompletion).succeeded() + } + + override predicate last(AstNode node, Completion c) { + node = super.getPat() and c.(MatchCompletion).failed() + or + last(super.getGuard().getCondition(), node, c) and c.(BooleanCompletion).failed() + or + last(super.getExpr(), node, c) + } +} + +class MatchExprTree extends PostOrderTree instanceof MatchExpr { + override predicate propagatesAbnormal(AstNode child) { + child = [super.getExpr(), super.getMatchArmList().getAnArm().getExpr()] + } + + override predicate first(AstNode node) { first(super.getExpr(), node) } + + override predicate succ(AstNode pred, AstNode succ, Completion c) { + // Edge from the scrutinee to the first arm. + last(super.getExpr(), pred, c) and succ = super.getMatchArmList().getArm(0).getPat() + or + // Edge from a failed match/guard in one arm to the beginning of the next arm. + exists(int i | + last(super.getMatchArmList().getArm(i), pred, c) and + first(super.getMatchArmList().getArm(i + 1), succ) and + c.(ConditionalCompletion).failed() + ) + or + // Edge from the end of each arm to the match expression. + last(super.getMatchArmList().getArm(_), pred, c) and succ = this and completionIsNormal(c) + } +} + +class MethodCallExprTree extends StandardPostOrderTree instanceof MethodCallExpr { + override ControlFlowTree getChildNode(int i) { + result = super.getReceiver() and + result = super.getArgList().getArg(i + 1) + } +} + +class OffsetOfExprTree extends LeafTree instanceof OffsetOfExpr { } + +// This covers all patterns as they all extend `Pat` +class PatExprTree extends LeafTree instanceof Pat { } + class PathExprTree extends LeafTree instanceof PathExpr { } + +class PrefixExprTree extends StandardPostOrderTree instanceof PrefixExpr { + override ControlFlowTree getChildNode(int i) { i = 0 and result = super.getExpr() } +} + +class RangeExprTree extends StandardPostOrderTree instanceof RangeExpr { + override ControlFlowTree getChildNode(int i) { + i = 0 and result = super.getStart() + or + i = 1 and result = super.getEnd() + } +} + +class RecordExprTree extends StandardPostOrderTree instanceof RecordExpr { + override ControlFlowTree getChildNode(int i) { + result = super.getRecordExprFieldList().getField(i).getExpr() + } +} + +class RefExprTree extends StandardPostOrderTree instanceof RefExpr { + override ControlFlowTree getChildNode(int i) { i = 0 and result = super.getExpr() } +} + +class ReturnExprTree extends PostOrderTree instanceof ReturnExpr { + override predicate propagatesAbnormal(AstNode child) { child = super.getExpr() } + + override predicate first(AstNode node) { + first(super.getExpr(), node) + or + not super.hasExpr() and node = this + } + + override predicate succ(AstNode pred, AstNode succ, Completion c) { + last(super.getExpr(), pred, c) and succ = this and completionIsNormal(c) + } +} + +class TupleExprTree extends StandardPostOrderTree instanceof TupleExpr { + override ControlFlowTree getChildNode(int i) { result = super.getField(i) } +} + +class TypeRefTree extends LeafTree instanceof TypeRef { } + +class UnderscoreExprTree extends LeafTree instanceof UnderscoreExpr { } + +// NOTE: `yield` is a reserved but unused keyword. +class YieldExprTree extends StandardPostOrderTree instanceof YieldExpr { + override ControlFlowTree getChildNode(int i) { i = 0 and result = super.getExpr() } +} + +// NOTE: `yeet` is experimental and not a part of Rust. +class YeetExprTree extends StandardPostOrderTree instanceof YeetExpr { + override ControlFlowTree getChildNode(int i) { i = 0 and result = super.getExpr() } +} diff --git a/rust/ql/lib/codeql/rust/controlflow/internal/Scope.qll b/rust/ql/lib/codeql/rust/controlflow/internal/Scope.qll index 9955d5da7fdc..bfc0d2ed3b9a 100644 --- a/rust/ql/lib/codeql/rust/controlflow/internal/Scope.qll +++ b/rust/ql/lib/codeql/rust/controlflow/internal/Scope.qll @@ -1,10 +1,27 @@ private import rust private import Completion +private import ControlFlowGraphImpl private import codeql.rust.elements.internal.generated.ParentChild -abstract class CfgScope extends AstNode { } +abstract class CfgScope extends AstNode { + /** Holds if `first` is executed first when entering scope. */ + abstract predicate scopeFirst(AstNode first); -class FunctionScope extends CfgScope, Function { } + /** Holds if scope is exited when `last` finishes with completion `c`. */ + abstract predicate scopeLast(AstNode last, Completion c); +} + +final class FunctionScope extends CfgScope, Function { + override predicate scopeFirst(AstNode node) { first(this.getBody(), node) } + + override predicate scopeLast(AstNode node, Completion c) { last(this.getBody(), node, c) } +} + +final class ClosureScope extends CfgScope, ClosureExpr { + override predicate scopeFirst(AstNode node) { first(this.getBody(), node) } + + override predicate scopeLast(AstNode node, Completion c) { last(this.getBody(), node, c) } +} /** * Gets the immediate parent of a non-`AstNode` element `e`. diff --git a/rust/ql/lib/codeql/rust/controlflow/internal/SuccessorType.qll b/rust/ql/lib/codeql/rust/controlflow/internal/SuccessorType.qll index 5ea12fc8a5c5..f7743e7275e3 100644 --- a/rust/ql/lib/codeql/rust/controlflow/internal/SuccessorType.qll +++ b/rust/ql/lib/codeql/rust/controlflow/internal/SuccessorType.qll @@ -1,9 +1,20 @@ +private import rust private import codeql.util.Boolean +newtype TLoopJumpType = + TContinueJump() or + TBreakJump() + +newtype TLabelType = + TLabel(string s) { any(Label l).getLifetime().getText() = s } or + TNoLabel() + cached newtype TSuccessorType = TSuccessorSuccessor() or TBooleanSuccessor(Boolean b) or + TMatchSuccessor(Boolean b) or + TLoopSuccessor(TLoopJumpType kind, TLabelType label) or TReturnSuccessor() /** The type of a control flow successor. */ @@ -28,13 +39,49 @@ abstract private class ConditionalSuccessor extends SuccessorTypeImpl { /** Gets the Boolean value of this successor. */ final boolean getValue() { result = value } - - override string toString() { result = this.getValue().toString() } } -/** A Boolean control flow successor. */ +/** A Boolean control flow successor for a boolean conditon. */ final class BooleanSuccessor extends ConditionalSuccessor, TBooleanSuccessor { BooleanSuccessor() { this = TBooleanSuccessor(value) } + + override string toString() { result = this.getValue().toString() } +} + +/** + * A control flow successor of a pattern match. + */ +final class MatchSuccessor extends ConditionalSuccessor, TMatchSuccessor { + MatchSuccessor() { this = TMatchSuccessor(value) } + + override string toString() { + if this.getValue() = true then result = "match" else result = "no-match" + } +} + +/** + * A control flow successor of a loop control flow expression, `continue` or `break`. + */ +final class LoopJumpSuccessor extends SuccessorTypeImpl, TLoopSuccessor { + final private TLoopJumpType getKind() { this = TLoopSuccessor(result, _) } + + final private TLabelType getLabelType() { this = TLoopSuccessor(_, result) } + + final predicate hasLabel() { this.getLabelType() = TLabel(_) } + + final string getLabelName() { this = TLoopSuccessor(_, TLabel(result)) } + + final predicate isContinue() { this.getKind() = TContinueJump() } + + final predicate isBreak() { this.getKind() = TBreakJump() } + + final override string toString() { + exists(string kind, string label | + (if this.isContinue() then kind = "continue" else kind = "break") and + (if this.hasLabel() then label = "(" + this.getLabelName() + ")" else label = "") and + result = kind + label + ) + } } /** diff --git a/rust/ql/test/library-tests/controlflow/Cfg.expected b/rust/ql/test/library-tests/controlflow/Cfg.expected index 6b660ee661f7..0e708488fcc9 100644 --- a/rust/ql/test/library-tests/controlflow/Cfg.expected +++ b/rust/ql/test/library-tests/controlflow/Cfg.expected @@ -1,92 +1,650 @@ nodes -| test.rs:1:1:7:1 | enter main | semmle.order | 1 | -| test.rs:1:1:7:1 | exit main | semmle.order | 2 | -| test.rs:1:1:7:1 | exit main (normal) | semmle.order | 3 | -| test.rs:1:1:7:1 | main | semmle.order | 4 | -| test.rs:1:18:7:1 | BlockExpr | semmle.order | 5 | -| test.rs:2:5:6:5 | IfExpr | semmle.order | 6 | -| test.rs:2:8:2:12 | LiteralExpr | semmle.order | 7 | -| test.rs:2:8:2:21 | BinaryExpr | semmle.order | 8 | -| test.rs:2:17:2:21 | LiteralExpr | semmle.order | 9 | -| test.rs:2:23:4:5 | BlockExpr | semmle.order | 10 | -| test.rs:3:9:3:20 | CallExpr | semmle.order | 11 | -| test.rs:3:19:3:19 | LiteralExpr | semmle.order | 12 | -| test.rs:4:12:6:5 | BlockExpr | semmle.order | 13 | -| test.rs:5:9:5:20 | CallExpr | semmle.order | 14 | -| test.rs:5:19:5:19 | LiteralExpr | semmle.order | 15 | -| test.rs:9:1:16:1 | decrement | semmle.order | 16 | -| test.rs:9:1:16:1 | enter decrement | semmle.order | 17 | -| test.rs:9:1:16:1 | exit decrement | semmle.order | 18 | -| test.rs:9:1:16:1 | exit decrement (normal) | semmle.order | 19 | -| test.rs:9:29:16:1 | BlockExpr | semmle.order | 20 | -| test.rs:11:5:15:5 | IfExpr | semmle.order | 21 | -| test.rs:11:8:11:8 | PathExpr | semmle.order | 22 | -| test.rs:11:8:11:13 | BinaryExpr | semmle.order | 23 | -| test.rs:11:13:11:13 | LiteralExpr | semmle.order | 24 | -| test.rs:11:15:13:5 | BlockExpr | semmle.order | 25 | -| test.rs:12:9:12:9 | LiteralExpr | semmle.order | 26 | -| test.rs:13:12:15:5 | BlockExpr | semmle.order | 27 | -| test.rs:14:9:14:9 | PathExpr | semmle.order | 28 | -| test.rs:14:9:14:13 | BinaryExpr | semmle.order | 29 | -| test.rs:14:13:14:13 | LiteralExpr | semmle.order | 30 | +| test.rs:1:1:4:1 | enter test_call | semmle.order | 1 | +| test.rs:1:1:4:1 | exit test_call | semmle.order | 2 | +| test.rs:1:1:4:1 | exit test_call (normal) | semmle.order | 3 | +| test.rs:1:24:4:1 | BlockExpr | semmle.order | 4 | +| test.rs:2:5:2:21 | PathExpr | semmle.order | 5 | +| test.rs:2:5:2:40 | CallExpr | semmle.order | 6 | +| test.rs:2:5:2:41 | ExprStmt | semmle.order | 7 | +| test.rs:2:23:2:26 | LiteralExpr | semmle.order | 8 | +| test.rs:2:29:2:33 | LiteralExpr | semmle.order | 9 | +| test.rs:2:36:2:39 | LiteralExpr | semmle.order | 10 | +| test.rs:3:5:3:19 | PathExpr | semmle.order | 11 | +| test.rs:3:5:3:23 | CallExpr | semmle.order | 12 | +| test.rs:3:5:3:24 | ExprStmt | semmle.order | 13 | +| test.rs:3:21:3:22 | LiteralExpr | semmle.order | 14 | +| test.rs:8:5:24:5 | enter test_break_and_continue | semmle.order | 15 | +| test.rs:8:5:24:5 | exit test_break_and_continue | semmle.order | 16 | +| test.rs:8:5:24:5 | exit test_break_and_continue (normal) | semmle.order | 17 | +| test.rs:9:9:9:22 | LetStmt | semmle.order | 18 | +| test.rs:9:13:9:17 | IdentPat | semmle.order | 19 | +| test.rs:9:21:9:21 | PathExpr | semmle.order | 20 | +| test.rs:10:9:22:9 | ExprStmt | semmle.order | 21 | +| test.rs:10:9:22:9 | LoopExpr | semmle.order | 22 | +| test.rs:10:14:22:9 | BlockExpr | semmle.order | 23 | +| test.rs:11:13:11:13 | PathExpr | semmle.order | 24 | +| test.rs:11:13:11:23 | BinaryExpr | semmle.order | 25 | +| test.rs:11:13:11:24 | ExprStmt | semmle.order | 26 | +| test.rs:11:17:11:20 | PathExpr | semmle.order | 27 | +| test.rs:11:17:11:23 | CallExpr | semmle.order | 28 | +| test.rs:11:22:11:22 | PathExpr | semmle.order | 29 | +| test.rs:12:13:14:13 | ExprStmt | semmle.order | 30 | +| test.rs:12:13:14:13 | IfExpr | semmle.order | 31 | +| test.rs:12:16:12:16 | PathExpr | semmle.order | 32 | +| test.rs:12:16:12:24 | BinaryExpr | semmle.order | 33 | +| test.rs:12:20:12:24 | LiteralExpr | semmle.order | 34 | +| test.rs:13:17:13:28 | ReturnExpr | semmle.order | 35 | +| test.rs:13:17:13:29 | ExprStmt | semmle.order | 36 | +| test.rs:13:24:13:28 | LiteralExpr | semmle.order | 37 | +| test.rs:15:13:17:13 | ExprStmt | semmle.order | 38 | +| test.rs:15:13:17:13 | IfExpr | semmle.order | 39 | +| test.rs:15:16:15:16 | PathExpr | semmle.order | 40 | +| test.rs:15:16:15:21 | BinaryExpr | semmle.order | 41 | +| test.rs:15:21:15:21 | LiteralExpr | semmle.order | 42 | +| test.rs:16:17:16:21 | BreakExpr | semmle.order | 43 | +| test.rs:16:17:16:22 | ExprStmt | semmle.order | 44 | +| test.rs:18:13:20:13 | ExprStmt | semmle.order | 45 | +| test.rs:18:13:20:13 | IfExpr | semmle.order | 46 | +| test.rs:18:16:18:16 | PathExpr | semmle.order | 47 | +| test.rs:18:16:18:20 | BinaryExpr | semmle.order | 48 | +| test.rs:18:16:18:25 | BinaryExpr | semmle.order | 49 | +| test.rs:18:20:18:20 | LiteralExpr | semmle.order | 50 | +| test.rs:18:25:18:25 | LiteralExpr | semmle.order | 51 | +| test.rs:19:17:19:24 | ContinueExpr | semmle.order | 52 | +| test.rs:19:17:19:25 | ExprStmt | semmle.order | 53 | +| test.rs:21:13:21:13 | PathExpr | semmle.order | 54 | +| test.rs:21:13:21:21 | BinaryExpr | semmle.order | 55 | +| test.rs:21:17:21:17 | PathExpr | semmle.order | 56 | +| test.rs:21:17:21:21 | BinaryExpr | semmle.order | 57 | +| test.rs:21:21:21:21 | LiteralExpr | semmle.order | 58 | +| test.rs:23:9:23:19 | ReturnExpr | semmle.order | 59 | +| test.rs:23:9:23:20 | ExprStmt | semmle.order | 60 | +| test.rs:23:16:23:19 | LiteralExpr | semmle.order | 61 | +| test.rs:26:5:38:5 | enter test_break_with_labels | semmle.order | 62 | +| test.rs:26:5:38:5 | exit test_break_with_labels | semmle.order | 63 | +| test.rs:26:5:38:5 | exit test_break_with_labels (normal) | semmle.order | 64 | +| test.rs:26:41:38:5 | BlockExpr | semmle.order | 65 | +| test.rs:27:9:36:9 | ExprStmt | semmle.order | 66 | +| test.rs:27:9:36:9 | LoopExpr | semmle.order | 67 | +| test.rs:27:22:36:9 | BlockExpr | semmle.order | 68 | +| test.rs:28:13:35:13 | LoopExpr | semmle.order | 69 | +| test.rs:29:17:33:17 | ExprStmt | semmle.order | 70 | +| test.rs:29:17:33:17 | IfExpr | semmle.order | 71 | +| test.rs:29:20:29:24 | LiteralExpr | semmle.order | 72 | +| test.rs:30:21:30:25 | BreakExpr | semmle.order | 73 | +| test.rs:30:21:30:26 | ExprStmt | semmle.order | 74 | +| test.rs:31:24:33:17 | IfExpr | semmle.order | 75 | +| test.rs:31:27:31:30 | LiteralExpr | semmle.order | 76 | +| test.rs:32:21:32:32 | BreakExpr | semmle.order | 77 | +| test.rs:32:21:32:33 | ExprStmt | semmle.order | 78 | +| test.rs:34:17:34:28 | BreakExpr | semmle.order | 79 | +| test.rs:34:17:34:29 | ExprStmt | semmle.order | 80 | +| test.rs:37:9:37:12 | LiteralExpr | semmle.order | 81 | +| test.rs:40:5:52:5 | enter test_continue_with_labels | semmle.order | 82 | +| test.rs:42:13:42:13 | LiteralExpr | semmle.order | 83 | +| test.rs:42:13:42:14 | ExprStmt | semmle.order | 84 | +| test.rs:44:17:48:17 | ExprStmt | semmle.order | 85 | +| test.rs:44:17:48:17 | IfExpr | semmle.order | 86 | +| test.rs:44:20:44:24 | LiteralExpr | semmle.order | 87 | +| test.rs:45:21:45:28 | ContinueExpr | semmle.order | 88 | +| test.rs:45:21:45:29 | ExprStmt | semmle.order | 89 | +| test.rs:46:24:48:17 | IfExpr | semmle.order | 90 | +| test.rs:46:27:46:30 | LiteralExpr | semmle.order | 91 | +| test.rs:47:21:47:35 | ContinueExpr | semmle.order | 92 | +| test.rs:47:21:47:36 | ExprStmt | semmle.order | 93 | +| test.rs:49:17:49:31 | ContinueExpr | semmle.order | 94 | +| test.rs:49:17:49:32 | ExprStmt | semmle.order | 95 | +| test.rs:55:1:58:1 | enter test_nested_function | semmle.order | 96 | +| test.rs:55:1:58:1 | exit test_nested_function | semmle.order | 97 | +| test.rs:55:1:58:1 | exit test_nested_function (normal) | semmle.order | 98 | +| test.rs:55:40:58:1 | BlockExpr | semmle.order | 99 | +| test.rs:56:5:56:28 | LetStmt | semmle.order | 100 | +| test.rs:56:9:56:15 | IdentPat | semmle.order | 101 | +| test.rs:56:19:56:27 | ClosureExpr | semmle.order | 102 | +| test.rs:56:19:56:27 | enter ClosureExpr | semmle.order | 103 | +| test.rs:56:19:56:27 | exit ClosureExpr | semmle.order | 104 | +| test.rs:56:19:56:27 | exit ClosureExpr (normal) | semmle.order | 105 | +| test.rs:56:23:56:23 | PathExpr | semmle.order | 106 | +| test.rs:56:23:56:27 | BinaryExpr | semmle.order | 107 | +| test.rs:56:27:56:27 | LiteralExpr | semmle.order | 108 | +| test.rs:57:5:57:11 | PathExpr | semmle.order | 109 | +| test.rs:57:5:57:23 | CallExpr | semmle.order | 110 | +| test.rs:57:13:57:19 | PathExpr | semmle.order | 111 | +| test.rs:57:13:57:22 | CallExpr | semmle.order | 112 | +| test.rs:57:21:57:21 | PathExpr | semmle.order | 113 | +| test.rs:62:5:68:5 | enter test_if_else | semmle.order | 114 | +| test.rs:62:5:68:5 | exit test_if_else | semmle.order | 115 | +| test.rs:62:5:68:5 | exit test_if_else (normal) | semmle.order | 116 | +| test.rs:62:36:68:5 | BlockExpr | semmle.order | 117 | +| test.rs:63:9:67:9 | IfExpr | semmle.order | 118 | +| test.rs:63:12:63:12 | PathExpr | semmle.order | 119 | +| test.rs:63:12:63:17 | BinaryExpr | semmle.order | 120 | +| test.rs:63:17:63:17 | LiteralExpr | semmle.order | 121 | +| test.rs:63:19:65:9 | BlockExpr | semmle.order | 122 | +| test.rs:64:13:64:13 | LiteralExpr | semmle.order | 123 | +| test.rs:65:16:67:9 | BlockExpr | semmle.order | 124 | +| test.rs:66:13:66:13 | PathExpr | semmle.order | 125 | +| test.rs:66:13:66:17 | BinaryExpr | semmle.order | 126 | +| test.rs:66:17:66:17 | LiteralExpr | semmle.order | 127 | +| test.rs:70:5:76:5 | enter test_if_let_else | semmle.order | 128 | +| test.rs:70:5:76:5 | exit test_if_let_else | semmle.order | 129 | +| test.rs:70:5:76:5 | exit test_if_let_else (normal) | semmle.order | 130 | +| test.rs:70:48:76:5 | BlockExpr | semmle.order | 131 | +| test.rs:71:9:75:9 | IfExpr | semmle.order | 132 | +| test.rs:71:12:71:26 | LetExpr | semmle.order | 133 | +| test.rs:71:16:71:22 | TupleStructPat | semmle.order | 134 | +| test.rs:71:28:73:9 | BlockExpr | semmle.order | 135 | +| test.rs:72:13:72:13 | PathExpr | semmle.order | 136 | +| test.rs:73:16:75:9 | BlockExpr | semmle.order | 137 | +| test.rs:74:13:74:13 | LiteralExpr | semmle.order | 138 | +| test.rs:78:5:83:5 | enter test_if_let | semmle.order | 139 | +| test.rs:78:5:83:5 | exit test_if_let | semmle.order | 140 | +| test.rs:78:5:83:5 | exit test_if_let (normal) | semmle.order | 141 | +| test.rs:78:43:83:5 | BlockExpr | semmle.order | 142 | +| test.rs:79:9:81:9 | ExprStmt | semmle.order | 143 | +| test.rs:79:9:81:9 | IfExpr | semmle.order | 144 | +| test.rs:79:12:79:26 | LetExpr | semmle.order | 145 | +| test.rs:79:16:79:22 | TupleStructPat | semmle.order | 146 | +| test.rs:79:28:81:9 | BlockExpr | semmle.order | 147 | +| test.rs:80:13:80:13 | PathExpr | semmle.order | 148 | +| test.rs:82:9:82:9 | LiteralExpr | semmle.order | 149 | +| test.rs:105:5:108:5 | enter test_and_operator | semmle.order | 150 | +| test.rs:105:5:108:5 | exit test_and_operator | semmle.order | 151 | +| test.rs:105:5:108:5 | exit test_and_operator (normal) | semmle.order | 152 | +| test.rs:105:61:108:5 | BlockExpr | semmle.order | 153 | +| test.rs:106:9:106:28 | LetStmt | semmle.order | 154 | +| test.rs:106:13:106:13 | IdentPat | semmle.order | 155 | +| test.rs:106:17:106:17 | PathExpr | semmle.order | 156 | +| test.rs:106:17:106:22 | BinaryExpr | semmle.order | 157 | +| test.rs:106:17:106:27 | BinaryExpr | semmle.order | 158 | +| test.rs:106:22:106:22 | PathExpr | semmle.order | 159 | +| test.rs:106:27:106:27 | PathExpr | semmle.order | 160 | +| test.rs:107:9:107:9 | PathExpr | semmle.order | 161 | +| test.rs:110:5:113:5 | enter test_or_operator | semmle.order | 162 | +| test.rs:110:5:113:5 | exit test_or_operator | semmle.order | 163 | +| test.rs:110:5:113:5 | exit test_or_operator (normal) | semmle.order | 164 | +| test.rs:110:60:113:5 | BlockExpr | semmle.order | 165 | +| test.rs:111:9:111:28 | LetStmt | semmle.order | 166 | +| test.rs:111:13:111:13 | IdentPat | semmle.order | 167 | +| test.rs:111:17:111:17 | PathExpr | semmle.order | 168 | +| test.rs:111:17:111:22 | BinaryExpr | semmle.order | 169 | +| test.rs:111:17:111:27 | BinaryExpr | semmle.order | 170 | +| test.rs:111:22:111:22 | PathExpr | semmle.order | 171 | +| test.rs:111:27:111:27 | PathExpr | semmle.order | 172 | +| test.rs:112:9:112:9 | PathExpr | semmle.order | 173 | +| test.rs:115:5:118:5 | enter test_or_operator_2 | semmle.order | 174 | +| test.rs:115:5:118:5 | exit test_or_operator_2 | semmle.order | 175 | +| test.rs:115:5:118:5 | exit test_or_operator_2 (normal) | semmle.order | 176 | +| test.rs:115:61:118:5 | BlockExpr | semmle.order | 177 | +| test.rs:116:9:116:36 | LetStmt | semmle.order | 178 | +| test.rs:116:13:116:13 | IdentPat | semmle.order | 179 | +| test.rs:116:17:116:17 | PathExpr | semmle.order | 180 | +| test.rs:116:17:116:30 | BinaryExpr | semmle.order | 181 | +| test.rs:116:17:116:35 | BinaryExpr | semmle.order | 182 | +| test.rs:117:9:117:9 | PathExpr | semmle.order | 183 | +| test.rs:122:1:128:1 | enter test_match | semmle.order | 184 | +| test.rs:122:1:128:1 | exit test_match | semmle.order | 185 | +| test.rs:122:1:128:1 | exit test_match (normal) | semmle.order | 186 | +| test.rs:122:44:128:1 | BlockExpr | semmle.order | 187 | +| test.rs:123:5:127:5 | MatchExpr | semmle.order | 188 | +| test.rs:123:11:123:21 | PathExpr | semmle.order | 189 | +| test.rs:124:9:124:23 | TupleStructPat | semmle.order | 190 | +| test.rs:124:28:124:28 | PathExpr | semmle.order | 191 | +| test.rs:124:28:124:33 | BinaryExpr | semmle.order | 192 | +| test.rs:124:32:124:33 | LiteralExpr | semmle.order | 193 | +| test.rs:125:9:125:23 | TupleStructPat | semmle.order | 194 | +| test.rs:125:28:125:28 | PathExpr | semmle.order | 195 | +| test.rs:126:9:126:20 | PathPat | semmle.order | 196 | +| test.rs:126:25:126:25 | LiteralExpr | semmle.order | 197 | +| test.rs:131:5:136:5 | enter test_infinite_loop | semmle.order | 198 | +| test.rs:132:9:134:9 | ExprStmt | semmle.order | 199 | +| test.rs:132:14:134:9 | BlockExpr | semmle.order | 200 | +| test.rs:133:13:133:13 | LiteralExpr | semmle.order | 201 | +| test.rs:138:5:143:5 | enter test_let_match | semmle.order | 202 | +| test.rs:138:5:143:5 | exit test_let_match | semmle.order | 203 | +| test.rs:138:5:143:5 | exit test_let_match (normal) | semmle.order | 204 | +| test.rs:138:39:143:5 | BlockExpr | semmle.order | 205 | +| test.rs:139:9:141:10 | LetStmt | semmle.order | 206 | +| test.rs:139:13:139:19 | TupleStructPat | semmle.order | 207 | +| test.rs:139:23:139:23 | PathExpr | semmle.order | 208 | +| test.rs:139:30:141:9 | BlockExpr | semmle.order | 209 | +| test.rs:140:13:140:27 | LiteralExpr | semmle.order | 210 | +| test.rs:142:9:142:9 | PathExpr | semmle.order | 211 | edges -| test.rs:1:1:7:1 | enter main | test.rs:2:8:2:12 | LiteralExpr | semmle.label | | -| test.rs:1:1:7:1 | enter main | test.rs:2:8:2:12 | LiteralExpr | semmle.order | 1 | -| test.rs:1:1:7:1 | exit main (normal) | test.rs:1:1:7:1 | exit main | semmle.label | | -| test.rs:1:1:7:1 | exit main (normal) | test.rs:1:1:7:1 | exit main | semmle.order | 1 | -| test.rs:1:1:7:1 | main | test.rs:1:1:7:1 | exit main (normal) | semmle.label | | -| test.rs:1:1:7:1 | main | test.rs:1:1:7:1 | exit main (normal) | semmle.order | 1 | -| test.rs:1:18:7:1 | BlockExpr | test.rs:1:1:7:1 | main | semmle.label | | -| test.rs:1:18:7:1 | BlockExpr | test.rs:1:1:7:1 | main | semmle.order | 1 | -| test.rs:2:5:6:5 | IfExpr | test.rs:1:18:7:1 | BlockExpr | semmle.label | | -| test.rs:2:5:6:5 | IfExpr | test.rs:1:18:7:1 | BlockExpr | semmle.order | 1 | -| test.rs:2:8:2:12 | LiteralExpr | test.rs:2:17:2:21 | LiteralExpr | semmle.label | | -| test.rs:2:8:2:12 | LiteralExpr | test.rs:2:17:2:21 | LiteralExpr | semmle.order | 1 | -| test.rs:2:8:2:21 | BinaryExpr | test.rs:3:19:3:19 | LiteralExpr | semmle.label | true | -| test.rs:2:8:2:21 | BinaryExpr | test.rs:3:19:3:19 | LiteralExpr | semmle.order | 1 | -| test.rs:2:8:2:21 | BinaryExpr | test.rs:5:19:5:19 | LiteralExpr | semmle.label | false | -| test.rs:2:8:2:21 | BinaryExpr | test.rs:5:19:5:19 | LiteralExpr | semmle.order | 2 | -| test.rs:2:17:2:21 | LiteralExpr | test.rs:2:8:2:21 | BinaryExpr | semmle.label | | -| test.rs:2:17:2:21 | LiteralExpr | test.rs:2:8:2:21 | BinaryExpr | semmle.order | 1 | -| test.rs:2:23:4:5 | BlockExpr | test.rs:2:5:6:5 | IfExpr | semmle.label | | -| test.rs:2:23:4:5 | BlockExpr | test.rs:2:5:6:5 | IfExpr | semmle.order | 1 | -| test.rs:3:9:3:20 | CallExpr | test.rs:2:23:4:5 | BlockExpr | semmle.label | | -| test.rs:3:9:3:20 | CallExpr | test.rs:2:23:4:5 | BlockExpr | semmle.order | 1 | -| test.rs:3:19:3:19 | LiteralExpr | test.rs:3:9:3:20 | CallExpr | semmle.label | | -| test.rs:3:19:3:19 | LiteralExpr | test.rs:3:9:3:20 | CallExpr | semmle.order | 1 | -| test.rs:4:12:6:5 | BlockExpr | test.rs:2:5:6:5 | IfExpr | semmle.label | | -| test.rs:4:12:6:5 | BlockExpr | test.rs:2:5:6:5 | IfExpr | semmle.order | 1 | -| test.rs:5:9:5:20 | CallExpr | test.rs:4:12:6:5 | BlockExpr | semmle.label | | -| test.rs:5:9:5:20 | CallExpr | test.rs:4:12:6:5 | BlockExpr | semmle.order | 1 | -| test.rs:5:19:5:19 | LiteralExpr | test.rs:5:9:5:20 | CallExpr | semmle.label | | -| test.rs:5:19:5:19 | LiteralExpr | test.rs:5:9:5:20 | CallExpr | semmle.order | 1 | -| test.rs:9:1:16:1 | decrement | test.rs:9:1:16:1 | exit decrement (normal) | semmle.label | | -| test.rs:9:1:16:1 | decrement | test.rs:9:1:16:1 | exit decrement (normal) | semmle.order | 1 | -| test.rs:9:1:16:1 | enter decrement | test.rs:11:8:11:8 | PathExpr | semmle.label | | -| test.rs:9:1:16:1 | enter decrement | test.rs:11:8:11:8 | PathExpr | semmle.order | 1 | -| test.rs:9:1:16:1 | exit decrement (normal) | test.rs:9:1:16:1 | exit decrement | semmle.label | | -| test.rs:9:1:16:1 | exit decrement (normal) | test.rs:9:1:16:1 | exit decrement | semmle.order | 1 | -| test.rs:9:29:16:1 | BlockExpr | test.rs:9:1:16:1 | decrement | semmle.label | | -| test.rs:9:29:16:1 | BlockExpr | test.rs:9:1:16:1 | decrement | semmle.order | 1 | -| test.rs:11:5:15:5 | IfExpr | test.rs:9:29:16:1 | BlockExpr | semmle.label | | -| test.rs:11:5:15:5 | IfExpr | test.rs:9:29:16:1 | BlockExpr | semmle.order | 1 | -| test.rs:11:8:11:8 | PathExpr | test.rs:11:13:11:13 | LiteralExpr | semmle.label | | -| test.rs:11:8:11:8 | PathExpr | test.rs:11:13:11:13 | LiteralExpr | semmle.order | 1 | -| test.rs:11:8:11:13 | BinaryExpr | test.rs:12:9:12:9 | LiteralExpr | semmle.label | true | -| test.rs:11:8:11:13 | BinaryExpr | test.rs:12:9:12:9 | LiteralExpr | semmle.order | 1 | -| test.rs:11:8:11:13 | BinaryExpr | test.rs:14:9:14:9 | PathExpr | semmle.label | false | -| test.rs:11:8:11:13 | BinaryExpr | test.rs:14:9:14:9 | PathExpr | semmle.order | 2 | -| test.rs:11:13:11:13 | LiteralExpr | test.rs:11:8:11:13 | BinaryExpr | semmle.label | | -| test.rs:11:13:11:13 | LiteralExpr | test.rs:11:8:11:13 | BinaryExpr | semmle.order | 1 | -| test.rs:11:15:13:5 | BlockExpr | test.rs:11:5:15:5 | IfExpr | semmle.label | | -| test.rs:11:15:13:5 | BlockExpr | test.rs:11:5:15:5 | IfExpr | semmle.order | 1 | -| test.rs:12:9:12:9 | LiteralExpr | test.rs:11:15:13:5 | BlockExpr | semmle.label | | -| test.rs:12:9:12:9 | LiteralExpr | test.rs:11:15:13:5 | BlockExpr | semmle.order | 1 | -| test.rs:13:12:15:5 | BlockExpr | test.rs:11:5:15:5 | IfExpr | semmle.label | | -| test.rs:13:12:15:5 | BlockExpr | test.rs:11:5:15:5 | IfExpr | semmle.order | 1 | -| test.rs:14:9:14:9 | PathExpr | test.rs:14:13:14:13 | LiteralExpr | semmle.label | | -| test.rs:14:9:14:9 | PathExpr | test.rs:14:13:14:13 | LiteralExpr | semmle.order | 1 | -| test.rs:14:9:14:13 | BinaryExpr | test.rs:13:12:15:5 | BlockExpr | semmle.label | | -| test.rs:14:9:14:13 | BinaryExpr | test.rs:13:12:15:5 | BlockExpr | semmle.order | 1 | -| test.rs:14:13:14:13 | LiteralExpr | test.rs:14:9:14:13 | BinaryExpr | semmle.label | | -| test.rs:14:13:14:13 | LiteralExpr | test.rs:14:9:14:13 | BinaryExpr | semmle.order | 1 | +| test.rs:1:1:4:1 | enter test_call | test.rs:2:5:2:41 | ExprStmt | semmle.label | | +| test.rs:1:1:4:1 | enter test_call | test.rs:2:5:2:41 | ExprStmt | semmle.order | 1 | +| test.rs:1:1:4:1 | exit test_call (normal) | test.rs:1:1:4:1 | exit test_call | semmle.label | | +| test.rs:1:1:4:1 | exit test_call (normal) | test.rs:1:1:4:1 | exit test_call | semmle.order | 1 | +| test.rs:1:24:4:1 | BlockExpr | test.rs:1:1:4:1 | exit test_call (normal) | semmle.label | | +| test.rs:1:24:4:1 | BlockExpr | test.rs:1:1:4:1 | exit test_call (normal) | semmle.order | 1 | +| test.rs:2:5:2:21 | PathExpr | test.rs:2:23:2:26 | LiteralExpr | semmle.label | | +| test.rs:2:5:2:21 | PathExpr | test.rs:2:23:2:26 | LiteralExpr | semmle.order | 1 | +| test.rs:2:5:2:40 | CallExpr | test.rs:3:5:3:24 | ExprStmt | semmle.label | | +| test.rs:2:5:2:40 | CallExpr | test.rs:3:5:3:24 | ExprStmt | semmle.order | 1 | +| test.rs:2:5:2:41 | ExprStmt | test.rs:2:5:2:21 | PathExpr | semmle.label | | +| test.rs:2:5:2:41 | ExprStmt | test.rs:2:5:2:21 | PathExpr | semmle.order | 1 | +| test.rs:2:23:2:26 | LiteralExpr | test.rs:2:29:2:33 | LiteralExpr | semmle.label | | +| test.rs:2:23:2:26 | LiteralExpr | test.rs:2:29:2:33 | LiteralExpr | semmle.order | 1 | +| test.rs:2:29:2:33 | LiteralExpr | test.rs:2:36:2:39 | LiteralExpr | semmle.label | | +| test.rs:2:29:2:33 | LiteralExpr | test.rs:2:36:2:39 | LiteralExpr | semmle.order | 1 | +| test.rs:2:36:2:39 | LiteralExpr | test.rs:2:5:2:40 | CallExpr | semmle.label | | +| test.rs:2:36:2:39 | LiteralExpr | test.rs:2:5:2:40 | CallExpr | semmle.order | 1 | +| test.rs:3:5:3:19 | PathExpr | test.rs:3:21:3:22 | LiteralExpr | semmle.label | | +| test.rs:3:5:3:19 | PathExpr | test.rs:3:21:3:22 | LiteralExpr | semmle.order | 1 | +| test.rs:3:5:3:23 | CallExpr | test.rs:1:24:4:1 | BlockExpr | semmle.label | | +| test.rs:3:5:3:23 | CallExpr | test.rs:1:24:4:1 | BlockExpr | semmle.order | 1 | +| test.rs:3:5:3:24 | ExprStmt | test.rs:3:5:3:19 | PathExpr | semmle.label | | +| test.rs:3:5:3:24 | ExprStmt | test.rs:3:5:3:19 | PathExpr | semmle.order | 1 | +| test.rs:3:21:3:22 | LiteralExpr | test.rs:3:5:3:23 | CallExpr | semmle.label | | +| test.rs:3:21:3:22 | LiteralExpr | test.rs:3:5:3:23 | CallExpr | semmle.order | 1 | +| test.rs:8:5:24:5 | enter test_break_and_continue | test.rs:9:9:9:22 | LetStmt | semmle.label | | +| test.rs:8:5:24:5 | enter test_break_and_continue | test.rs:9:9:9:22 | LetStmt | semmle.order | 1 | +| test.rs:8:5:24:5 | exit test_break_and_continue (normal) | test.rs:8:5:24:5 | exit test_break_and_continue | semmle.label | | +| test.rs:8:5:24:5 | exit test_break_and_continue (normal) | test.rs:8:5:24:5 | exit test_break_and_continue | semmle.order | 1 | +| test.rs:9:9:9:22 | LetStmt | test.rs:9:21:9:21 | PathExpr | semmle.label | | +| test.rs:9:9:9:22 | LetStmt | test.rs:9:21:9:21 | PathExpr | semmle.order | 1 | +| test.rs:9:13:9:17 | IdentPat | test.rs:10:9:22:9 | ExprStmt | semmle.label | match, no-match | +| test.rs:9:13:9:17 | IdentPat | test.rs:10:9:22:9 | ExprStmt | semmle.order | 1 | +| test.rs:9:13:9:17 | IdentPat | test.rs:10:9:22:9 | ExprStmt | semmle.order | 2 | +| test.rs:9:21:9:21 | PathExpr | test.rs:9:13:9:17 | IdentPat | semmle.label | | +| test.rs:9:21:9:21 | PathExpr | test.rs:9:13:9:17 | IdentPat | semmle.order | 1 | +| test.rs:10:9:22:9 | ExprStmt | test.rs:11:13:11:24 | ExprStmt | semmle.label | | +| test.rs:10:9:22:9 | ExprStmt | test.rs:11:13:11:24 | ExprStmt | semmle.order | 1 | +| test.rs:10:9:22:9 | LoopExpr | test.rs:23:9:23:20 | ExprStmt | semmle.label | | +| test.rs:10:9:22:9 | LoopExpr | test.rs:23:9:23:20 | ExprStmt | semmle.order | 1 | +| test.rs:10:14:22:9 | BlockExpr | test.rs:11:13:11:24 | ExprStmt | semmle.label | | +| test.rs:10:14:22:9 | BlockExpr | test.rs:11:13:11:24 | ExprStmt | semmle.order | 1 | +| test.rs:11:13:11:13 | PathExpr | test.rs:11:17:11:20 | PathExpr | semmle.label | | +| test.rs:11:13:11:13 | PathExpr | test.rs:11:17:11:20 | PathExpr | semmle.order | 1 | +| test.rs:11:13:11:23 | BinaryExpr | test.rs:12:13:14:13 | ExprStmt | semmle.label | | +| test.rs:11:13:11:23 | BinaryExpr | test.rs:12:13:14:13 | ExprStmt | semmle.order | 1 | +| test.rs:11:13:11:24 | ExprStmt | test.rs:11:13:11:13 | PathExpr | semmle.label | | +| test.rs:11:13:11:24 | ExprStmt | test.rs:11:13:11:13 | PathExpr | semmle.order | 1 | +| test.rs:11:17:11:20 | PathExpr | test.rs:11:22:11:22 | PathExpr | semmle.label | | +| test.rs:11:17:11:20 | PathExpr | test.rs:11:22:11:22 | PathExpr | semmle.order | 1 | +| test.rs:11:17:11:23 | CallExpr | test.rs:11:13:11:23 | BinaryExpr | semmle.label | | +| test.rs:11:17:11:23 | CallExpr | test.rs:11:13:11:23 | BinaryExpr | semmle.order | 1 | +| test.rs:11:22:11:22 | PathExpr | test.rs:11:17:11:23 | CallExpr | semmle.label | | +| test.rs:11:22:11:22 | PathExpr | test.rs:11:17:11:23 | CallExpr | semmle.order | 1 | +| test.rs:12:13:14:13 | ExprStmt | test.rs:12:16:12:16 | PathExpr | semmle.label | | +| test.rs:12:13:14:13 | ExprStmt | test.rs:12:16:12:16 | PathExpr | semmle.order | 1 | +| test.rs:12:13:14:13 | IfExpr | test.rs:15:13:17:13 | ExprStmt | semmle.label | | +| test.rs:12:13:14:13 | IfExpr | test.rs:15:13:17:13 | ExprStmt | semmle.order | 1 | +| test.rs:12:16:12:16 | PathExpr | test.rs:12:20:12:24 | LiteralExpr | semmle.label | | +| test.rs:12:16:12:16 | PathExpr | test.rs:12:20:12:24 | LiteralExpr | semmle.order | 1 | +| test.rs:12:16:12:24 | BinaryExpr | test.rs:12:13:14:13 | IfExpr | semmle.label | false | +| test.rs:12:16:12:24 | BinaryExpr | test.rs:12:13:14:13 | IfExpr | semmle.order | 1 | +| test.rs:12:16:12:24 | BinaryExpr | test.rs:13:17:13:29 | ExprStmt | semmle.label | true | +| test.rs:12:16:12:24 | BinaryExpr | test.rs:13:17:13:29 | ExprStmt | semmle.order | 2 | +| test.rs:12:20:12:24 | LiteralExpr | test.rs:12:16:12:24 | BinaryExpr | semmle.label | | +| test.rs:12:20:12:24 | LiteralExpr | test.rs:12:16:12:24 | BinaryExpr | semmle.order | 1 | +| test.rs:13:17:13:28 | ReturnExpr | test.rs:8:5:24:5 | exit test_break_and_continue (normal) | semmle.label | return | +| test.rs:13:17:13:28 | ReturnExpr | test.rs:8:5:24:5 | exit test_break_and_continue (normal) | semmle.order | 1 | +| test.rs:13:17:13:29 | ExprStmt | test.rs:13:24:13:28 | LiteralExpr | semmle.label | | +| test.rs:13:17:13:29 | ExprStmt | test.rs:13:24:13:28 | LiteralExpr | semmle.order | 1 | +| test.rs:13:24:13:28 | LiteralExpr | test.rs:13:17:13:28 | ReturnExpr | semmle.label | | +| test.rs:13:24:13:28 | LiteralExpr | test.rs:13:17:13:28 | ReturnExpr | semmle.order | 1 | +| test.rs:15:13:17:13 | ExprStmt | test.rs:15:16:15:16 | PathExpr | semmle.label | | +| test.rs:15:13:17:13 | ExprStmt | test.rs:15:16:15:16 | PathExpr | semmle.order | 1 | +| test.rs:15:13:17:13 | IfExpr | test.rs:18:13:20:13 | ExprStmt | semmle.label | | +| test.rs:15:13:17:13 | IfExpr | test.rs:18:13:20:13 | ExprStmt | semmle.order | 1 | +| test.rs:15:16:15:16 | PathExpr | test.rs:15:21:15:21 | LiteralExpr | semmle.label | | +| test.rs:15:16:15:16 | PathExpr | test.rs:15:21:15:21 | LiteralExpr | semmle.order | 1 | +| test.rs:15:16:15:21 | BinaryExpr | test.rs:15:13:17:13 | IfExpr | semmle.label | false | +| test.rs:15:16:15:21 | BinaryExpr | test.rs:15:13:17:13 | IfExpr | semmle.order | 1 | +| test.rs:15:16:15:21 | BinaryExpr | test.rs:16:17:16:22 | ExprStmt | semmle.label | true | +| test.rs:15:16:15:21 | BinaryExpr | test.rs:16:17:16:22 | ExprStmt | semmle.order | 2 | +| test.rs:15:21:15:21 | LiteralExpr | test.rs:15:16:15:21 | BinaryExpr | semmle.label | | +| test.rs:15:21:15:21 | LiteralExpr | test.rs:15:16:15:21 | BinaryExpr | semmle.order | 1 | +| test.rs:16:17:16:21 | BreakExpr | test.rs:10:9:22:9 | LoopExpr | semmle.label | break | +| test.rs:16:17:16:21 | BreakExpr | test.rs:10:9:22:9 | LoopExpr | semmle.order | 1 | +| test.rs:16:17:16:22 | ExprStmt | test.rs:16:17:16:21 | BreakExpr | semmle.label | | +| test.rs:16:17:16:22 | ExprStmt | test.rs:16:17:16:21 | BreakExpr | semmle.order | 1 | +| test.rs:18:13:20:13 | ExprStmt | test.rs:18:16:18:16 | PathExpr | semmle.label | | +| test.rs:18:13:20:13 | ExprStmt | test.rs:18:16:18:16 | PathExpr | semmle.order | 1 | +| test.rs:18:13:20:13 | IfExpr | test.rs:21:13:21:13 | PathExpr | semmle.label | | +| test.rs:18:13:20:13 | IfExpr | test.rs:21:13:21:13 | PathExpr | semmle.order | 1 | +| test.rs:18:16:18:16 | PathExpr | test.rs:18:20:18:20 | LiteralExpr | semmle.label | | +| test.rs:18:16:18:16 | PathExpr | test.rs:18:20:18:20 | LiteralExpr | semmle.order | 1 | +| test.rs:18:16:18:20 | BinaryExpr | test.rs:18:25:18:25 | LiteralExpr | semmle.label | | +| test.rs:18:16:18:20 | BinaryExpr | test.rs:18:25:18:25 | LiteralExpr | semmle.order | 1 | +| test.rs:18:16:18:25 | BinaryExpr | test.rs:18:13:20:13 | IfExpr | semmle.label | false | +| test.rs:18:16:18:25 | BinaryExpr | test.rs:18:13:20:13 | IfExpr | semmle.order | 1 | +| test.rs:18:16:18:25 | BinaryExpr | test.rs:19:17:19:25 | ExprStmt | semmle.label | true | +| test.rs:18:16:18:25 | BinaryExpr | test.rs:19:17:19:25 | ExprStmt | semmle.order | 2 | +| test.rs:18:20:18:20 | LiteralExpr | test.rs:18:16:18:20 | BinaryExpr | semmle.label | | +| test.rs:18:20:18:20 | LiteralExpr | test.rs:18:16:18:20 | BinaryExpr | semmle.order | 1 | +| test.rs:18:25:18:25 | LiteralExpr | test.rs:18:16:18:25 | BinaryExpr | semmle.label | | +| test.rs:18:25:18:25 | LiteralExpr | test.rs:18:16:18:25 | BinaryExpr | semmle.order | 1 | +| test.rs:19:17:19:24 | ContinueExpr | test.rs:11:13:11:24 | ExprStmt | semmle.label | continue | +| test.rs:19:17:19:24 | ContinueExpr | test.rs:11:13:11:24 | ExprStmt | semmle.order | 1 | +| test.rs:19:17:19:25 | ExprStmt | test.rs:19:17:19:24 | ContinueExpr | semmle.label | | +| test.rs:19:17:19:25 | ExprStmt | test.rs:19:17:19:24 | ContinueExpr | semmle.order | 1 | +| test.rs:21:13:21:13 | PathExpr | test.rs:21:17:21:17 | PathExpr | semmle.label | | +| test.rs:21:13:21:13 | PathExpr | test.rs:21:17:21:17 | PathExpr | semmle.order | 1 | +| test.rs:21:13:21:21 | BinaryExpr | test.rs:10:14:22:9 | BlockExpr | semmle.label | | +| test.rs:21:13:21:21 | BinaryExpr | test.rs:10:14:22:9 | BlockExpr | semmle.order | 1 | +| test.rs:21:17:21:17 | PathExpr | test.rs:21:21:21:21 | LiteralExpr | semmle.label | | +| test.rs:21:17:21:17 | PathExpr | test.rs:21:21:21:21 | LiteralExpr | semmle.order | 1 | +| test.rs:21:17:21:21 | BinaryExpr | test.rs:21:13:21:21 | BinaryExpr | semmle.label | | +| test.rs:21:17:21:21 | BinaryExpr | test.rs:21:13:21:21 | BinaryExpr | semmle.order | 1 | +| test.rs:21:21:21:21 | LiteralExpr | test.rs:21:17:21:21 | BinaryExpr | semmle.label | | +| test.rs:21:21:21:21 | LiteralExpr | test.rs:21:17:21:21 | BinaryExpr | semmle.order | 1 | +| test.rs:23:9:23:19 | ReturnExpr | test.rs:8:5:24:5 | exit test_break_and_continue (normal) | semmle.label | return | +| test.rs:23:9:23:19 | ReturnExpr | test.rs:8:5:24:5 | exit test_break_and_continue (normal) | semmle.order | 1 | +| test.rs:23:9:23:20 | ExprStmt | test.rs:23:16:23:19 | LiteralExpr | semmle.label | | +| test.rs:23:9:23:20 | ExprStmt | test.rs:23:16:23:19 | LiteralExpr | semmle.order | 1 | +| test.rs:23:16:23:19 | LiteralExpr | test.rs:23:9:23:19 | ReturnExpr | semmle.label | | +| test.rs:23:16:23:19 | LiteralExpr | test.rs:23:9:23:19 | ReturnExpr | semmle.order | 1 | +| test.rs:26:5:38:5 | enter test_break_with_labels | test.rs:27:9:36:9 | ExprStmt | semmle.label | | +| test.rs:26:5:38:5 | enter test_break_with_labels | test.rs:27:9:36:9 | ExprStmt | semmle.order | 1 | +| test.rs:26:5:38:5 | exit test_break_with_labels (normal) | test.rs:26:5:38:5 | exit test_break_with_labels | semmle.label | | +| test.rs:26:5:38:5 | exit test_break_with_labels (normal) | test.rs:26:5:38:5 | exit test_break_with_labels | semmle.order | 1 | +| test.rs:26:41:38:5 | BlockExpr | test.rs:26:5:38:5 | exit test_break_with_labels (normal) | semmle.label | | +| test.rs:26:41:38:5 | BlockExpr | test.rs:26:5:38:5 | exit test_break_with_labels (normal) | semmle.order | 1 | +| test.rs:27:9:36:9 | ExprStmt | test.rs:29:17:33:17 | ExprStmt | semmle.label | | +| test.rs:27:9:36:9 | ExprStmt | test.rs:29:17:33:17 | ExprStmt | semmle.order | 1 | +| test.rs:27:9:36:9 | LoopExpr | test.rs:37:9:37:12 | LiteralExpr | semmle.label | | +| test.rs:27:9:36:9 | LoopExpr | test.rs:37:9:37:12 | LiteralExpr | semmle.order | 1 | +| test.rs:27:22:36:9 | BlockExpr | test.rs:29:17:33:17 | ExprStmt | semmle.label | | +| test.rs:27:22:36:9 | BlockExpr | test.rs:29:17:33:17 | ExprStmt | semmle.order | 1 | +| test.rs:28:13:35:13 | LoopExpr | test.rs:27:22:36:9 | BlockExpr | semmle.label | | +| test.rs:28:13:35:13 | LoopExpr | test.rs:27:22:36:9 | BlockExpr | semmle.order | 1 | +| test.rs:29:17:33:17 | ExprStmt | test.rs:29:20:29:24 | LiteralExpr | semmle.label | | +| test.rs:29:17:33:17 | ExprStmt | test.rs:29:20:29:24 | LiteralExpr | semmle.order | 1 | +| test.rs:29:17:33:17 | IfExpr | test.rs:34:17:34:29 | ExprStmt | semmle.label | | +| test.rs:29:17:33:17 | IfExpr | test.rs:34:17:34:29 | ExprStmt | semmle.order | 1 | +| test.rs:29:20:29:24 | LiteralExpr | test.rs:30:21:30:26 | ExprStmt | semmle.label | true | +| test.rs:29:20:29:24 | LiteralExpr | test.rs:30:21:30:26 | ExprStmt | semmle.order | 1 | +| test.rs:29:20:29:24 | LiteralExpr | test.rs:31:27:31:30 | LiteralExpr | semmle.label | false | +| test.rs:29:20:29:24 | LiteralExpr | test.rs:31:27:31:30 | LiteralExpr | semmle.order | 2 | +| test.rs:30:21:30:25 | BreakExpr | test.rs:28:13:35:13 | LoopExpr | semmle.label | break | +| test.rs:30:21:30:25 | BreakExpr | test.rs:28:13:35:13 | LoopExpr | semmle.order | 1 | +| test.rs:30:21:30:26 | ExprStmt | test.rs:30:21:30:25 | BreakExpr | semmle.label | | +| test.rs:30:21:30:26 | ExprStmt | test.rs:30:21:30:25 | BreakExpr | semmle.order | 1 | +| test.rs:31:24:33:17 | IfExpr | test.rs:29:17:33:17 | IfExpr | semmle.label | | +| test.rs:31:24:33:17 | IfExpr | test.rs:29:17:33:17 | IfExpr | semmle.order | 1 | +| test.rs:31:27:31:30 | LiteralExpr | test.rs:31:24:33:17 | IfExpr | semmle.label | false | +| test.rs:31:27:31:30 | LiteralExpr | test.rs:31:24:33:17 | IfExpr | semmle.order | 1 | +| test.rs:31:27:31:30 | LiteralExpr | test.rs:32:21:32:33 | ExprStmt | semmle.label | true | +| test.rs:31:27:31:30 | LiteralExpr | test.rs:32:21:32:33 | ExprStmt | semmle.order | 2 | +| test.rs:32:21:32:32 | BreakExpr | test.rs:27:9:36:9 | LoopExpr | semmle.label | break('outer) | +| test.rs:32:21:32:32 | BreakExpr | test.rs:27:9:36:9 | LoopExpr | semmle.order | 1 | +| test.rs:32:21:32:33 | ExprStmt | test.rs:32:21:32:32 | BreakExpr | semmle.label | | +| test.rs:32:21:32:33 | ExprStmt | test.rs:32:21:32:32 | BreakExpr | semmle.order | 1 | +| test.rs:34:17:34:28 | BreakExpr | test.rs:28:13:35:13 | LoopExpr | semmle.label | break('inner) | +| test.rs:34:17:34:28 | BreakExpr | test.rs:28:13:35:13 | LoopExpr | semmle.order | 1 | +| test.rs:34:17:34:29 | ExprStmt | test.rs:34:17:34:28 | BreakExpr | semmle.label | | +| test.rs:34:17:34:29 | ExprStmt | test.rs:34:17:34:28 | BreakExpr | semmle.order | 1 | +| test.rs:37:9:37:12 | LiteralExpr | test.rs:26:41:38:5 | BlockExpr | semmle.label | | +| test.rs:37:9:37:12 | LiteralExpr | test.rs:26:41:38:5 | BlockExpr | semmle.order | 1 | +| test.rs:40:5:52:5 | enter test_continue_with_labels | test.rs:42:13:42:14 | ExprStmt | semmle.label | | +| test.rs:40:5:52:5 | enter test_continue_with_labels | test.rs:42:13:42:14 | ExprStmt | semmle.order | 1 | +| test.rs:42:13:42:13 | LiteralExpr | test.rs:44:17:48:17 | ExprStmt | semmle.label | | +| test.rs:42:13:42:13 | LiteralExpr | test.rs:44:17:48:17 | ExprStmt | semmle.order | 1 | +| test.rs:42:13:42:14 | ExprStmt | test.rs:42:13:42:13 | LiteralExpr | semmle.label | | +| test.rs:42:13:42:14 | ExprStmt | test.rs:42:13:42:13 | LiteralExpr | semmle.order | 1 | +| test.rs:44:17:48:17 | ExprStmt | test.rs:44:20:44:24 | LiteralExpr | semmle.label | | +| test.rs:44:17:48:17 | ExprStmt | test.rs:44:20:44:24 | LiteralExpr | semmle.order | 1 | +| test.rs:44:17:48:17 | IfExpr | test.rs:49:17:49:32 | ExprStmt | semmle.label | | +| test.rs:44:17:48:17 | IfExpr | test.rs:49:17:49:32 | ExprStmt | semmle.order | 1 | +| test.rs:44:20:44:24 | LiteralExpr | test.rs:45:21:45:29 | ExprStmt | semmle.label | true | +| test.rs:44:20:44:24 | LiteralExpr | test.rs:45:21:45:29 | ExprStmt | semmle.order | 1 | +| test.rs:44:20:44:24 | LiteralExpr | test.rs:46:27:46:30 | LiteralExpr | semmle.label | false | +| test.rs:44:20:44:24 | LiteralExpr | test.rs:46:27:46:30 | LiteralExpr | semmle.order | 2 | +| test.rs:45:21:45:28 | ContinueExpr | test.rs:44:17:48:17 | ExprStmt | semmle.label | continue | +| test.rs:45:21:45:28 | ContinueExpr | test.rs:44:17:48:17 | ExprStmt | semmle.order | 1 | +| test.rs:45:21:45:29 | ExprStmt | test.rs:45:21:45:28 | ContinueExpr | semmle.label | | +| test.rs:45:21:45:29 | ExprStmt | test.rs:45:21:45:28 | ContinueExpr | semmle.order | 1 | +| test.rs:46:24:48:17 | IfExpr | test.rs:44:17:48:17 | IfExpr | semmle.label | | +| test.rs:46:24:48:17 | IfExpr | test.rs:44:17:48:17 | IfExpr | semmle.order | 1 | +| test.rs:46:27:46:30 | LiteralExpr | test.rs:46:24:48:17 | IfExpr | semmle.label | false | +| test.rs:46:27:46:30 | LiteralExpr | test.rs:46:24:48:17 | IfExpr | semmle.order | 1 | +| test.rs:46:27:46:30 | LiteralExpr | test.rs:47:21:47:36 | ExprStmt | semmle.label | true | +| test.rs:46:27:46:30 | LiteralExpr | test.rs:47:21:47:36 | ExprStmt | semmle.order | 2 | +| test.rs:47:21:47:35 | ContinueExpr | test.rs:42:13:42:14 | ExprStmt | semmle.label | continue('outer) | +| test.rs:47:21:47:35 | ContinueExpr | test.rs:42:13:42:14 | ExprStmt | semmle.order | 1 | +| test.rs:47:21:47:36 | ExprStmt | test.rs:47:21:47:35 | ContinueExpr | semmle.label | | +| test.rs:47:21:47:36 | ExprStmt | test.rs:47:21:47:35 | ContinueExpr | semmle.order | 1 | +| test.rs:49:17:49:31 | ContinueExpr | test.rs:44:17:48:17 | ExprStmt | semmle.label | continue('inner) | +| test.rs:49:17:49:31 | ContinueExpr | test.rs:44:17:48:17 | ExprStmt | semmle.order | 1 | +| test.rs:49:17:49:32 | ExprStmt | test.rs:49:17:49:31 | ContinueExpr | semmle.label | | +| test.rs:49:17:49:32 | ExprStmt | test.rs:49:17:49:31 | ContinueExpr | semmle.order | 1 | +| test.rs:55:1:58:1 | enter test_nested_function | test.rs:56:5:56:28 | LetStmt | semmle.label | | +| test.rs:55:1:58:1 | enter test_nested_function | test.rs:56:5:56:28 | LetStmt | semmle.order | 1 | +| test.rs:55:1:58:1 | exit test_nested_function (normal) | test.rs:55:1:58:1 | exit test_nested_function | semmle.label | | +| test.rs:55:1:58:1 | exit test_nested_function (normal) | test.rs:55:1:58:1 | exit test_nested_function | semmle.order | 1 | +| test.rs:55:40:58:1 | BlockExpr | test.rs:55:1:58:1 | exit test_nested_function (normal) | semmle.label | | +| test.rs:55:40:58:1 | BlockExpr | test.rs:55:1:58:1 | exit test_nested_function (normal) | semmle.order | 1 | +| test.rs:56:5:56:28 | LetStmt | test.rs:56:19:56:27 | ClosureExpr | semmle.label | | +| test.rs:56:5:56:28 | LetStmt | test.rs:56:19:56:27 | ClosureExpr | semmle.order | 1 | +| test.rs:56:9:56:15 | IdentPat | test.rs:57:5:57:11 | PathExpr | semmle.label | match, no-match | +| test.rs:56:9:56:15 | IdentPat | test.rs:57:5:57:11 | PathExpr | semmle.order | 1 | +| test.rs:56:9:56:15 | IdentPat | test.rs:57:5:57:11 | PathExpr | semmle.order | 2 | +| test.rs:56:19:56:27 | ClosureExpr | test.rs:56:9:56:15 | IdentPat | semmle.label | | +| test.rs:56:19:56:27 | ClosureExpr | test.rs:56:9:56:15 | IdentPat | semmle.order | 1 | +| test.rs:56:19:56:27 | enter ClosureExpr | test.rs:56:23:56:23 | PathExpr | semmle.label | | +| test.rs:56:19:56:27 | enter ClosureExpr | test.rs:56:23:56:23 | PathExpr | semmle.order | 1 | +| test.rs:56:19:56:27 | exit ClosureExpr (normal) | test.rs:56:19:56:27 | exit ClosureExpr | semmle.label | | +| test.rs:56:19:56:27 | exit ClosureExpr (normal) | test.rs:56:19:56:27 | exit ClosureExpr | semmle.order | 1 | +| test.rs:56:23:56:23 | PathExpr | test.rs:56:27:56:27 | LiteralExpr | semmle.label | | +| test.rs:56:23:56:23 | PathExpr | test.rs:56:27:56:27 | LiteralExpr | semmle.order | 1 | +| test.rs:56:23:56:27 | BinaryExpr | test.rs:56:19:56:27 | exit ClosureExpr (normal) | semmle.label | | +| test.rs:56:23:56:27 | BinaryExpr | test.rs:56:19:56:27 | exit ClosureExpr (normal) | semmle.order | 1 | +| test.rs:56:27:56:27 | LiteralExpr | test.rs:56:23:56:27 | BinaryExpr | semmle.label | | +| test.rs:56:27:56:27 | LiteralExpr | test.rs:56:23:56:27 | BinaryExpr | semmle.order | 1 | +| test.rs:57:5:57:11 | PathExpr | test.rs:57:13:57:19 | PathExpr | semmle.label | | +| test.rs:57:5:57:11 | PathExpr | test.rs:57:13:57:19 | PathExpr | semmle.order | 1 | +| test.rs:57:5:57:23 | CallExpr | test.rs:55:40:58:1 | BlockExpr | semmle.label | | +| test.rs:57:5:57:23 | CallExpr | test.rs:55:40:58:1 | BlockExpr | semmle.order | 1 | +| test.rs:57:13:57:19 | PathExpr | test.rs:57:21:57:21 | PathExpr | semmle.label | | +| test.rs:57:13:57:19 | PathExpr | test.rs:57:21:57:21 | PathExpr | semmle.order | 1 | +| test.rs:57:13:57:22 | CallExpr | test.rs:57:5:57:23 | CallExpr | semmle.label | | +| test.rs:57:13:57:22 | CallExpr | test.rs:57:5:57:23 | CallExpr | semmle.order | 1 | +| test.rs:57:21:57:21 | PathExpr | test.rs:57:13:57:22 | CallExpr | semmle.label | | +| test.rs:57:21:57:21 | PathExpr | test.rs:57:13:57:22 | CallExpr | semmle.order | 1 | +| test.rs:62:5:68:5 | enter test_if_else | test.rs:63:12:63:12 | PathExpr | semmle.label | | +| test.rs:62:5:68:5 | enter test_if_else | test.rs:63:12:63:12 | PathExpr | semmle.order | 1 | +| test.rs:62:5:68:5 | exit test_if_else (normal) | test.rs:62:5:68:5 | exit test_if_else | semmle.label | | +| test.rs:62:5:68:5 | exit test_if_else (normal) | test.rs:62:5:68:5 | exit test_if_else | semmle.order | 1 | +| test.rs:62:36:68:5 | BlockExpr | test.rs:62:5:68:5 | exit test_if_else (normal) | semmle.label | | +| test.rs:62:36:68:5 | BlockExpr | test.rs:62:5:68:5 | exit test_if_else (normal) | semmle.order | 1 | +| test.rs:63:9:67:9 | IfExpr | test.rs:62:36:68:5 | BlockExpr | semmle.label | | +| test.rs:63:9:67:9 | IfExpr | test.rs:62:36:68:5 | BlockExpr | semmle.order | 1 | +| test.rs:63:12:63:12 | PathExpr | test.rs:63:17:63:17 | LiteralExpr | semmle.label | | +| test.rs:63:12:63:12 | PathExpr | test.rs:63:17:63:17 | LiteralExpr | semmle.order | 1 | +| test.rs:63:12:63:17 | BinaryExpr | test.rs:64:13:64:13 | LiteralExpr | semmle.label | true | +| test.rs:63:12:63:17 | BinaryExpr | test.rs:64:13:64:13 | LiteralExpr | semmle.order | 1 | +| test.rs:63:12:63:17 | BinaryExpr | test.rs:66:13:66:13 | PathExpr | semmle.label | false | +| test.rs:63:12:63:17 | BinaryExpr | test.rs:66:13:66:13 | PathExpr | semmle.order | 2 | +| test.rs:63:17:63:17 | LiteralExpr | test.rs:63:12:63:17 | BinaryExpr | semmle.label | | +| test.rs:63:17:63:17 | LiteralExpr | test.rs:63:12:63:17 | BinaryExpr | semmle.order | 1 | +| test.rs:63:19:65:9 | BlockExpr | test.rs:63:9:67:9 | IfExpr | semmle.label | | +| test.rs:63:19:65:9 | BlockExpr | test.rs:63:9:67:9 | IfExpr | semmle.order | 1 | +| test.rs:64:13:64:13 | LiteralExpr | test.rs:63:19:65:9 | BlockExpr | semmle.label | | +| test.rs:64:13:64:13 | LiteralExpr | test.rs:63:19:65:9 | BlockExpr | semmle.order | 1 | +| test.rs:65:16:67:9 | BlockExpr | test.rs:63:9:67:9 | IfExpr | semmle.label | | +| test.rs:65:16:67:9 | BlockExpr | test.rs:63:9:67:9 | IfExpr | semmle.order | 1 | +| test.rs:66:13:66:13 | PathExpr | test.rs:66:17:66:17 | LiteralExpr | semmle.label | | +| test.rs:66:13:66:13 | PathExpr | test.rs:66:17:66:17 | LiteralExpr | semmle.order | 1 | +| test.rs:66:13:66:17 | BinaryExpr | test.rs:65:16:67:9 | BlockExpr | semmle.label | | +| test.rs:66:13:66:17 | BinaryExpr | test.rs:65:16:67:9 | BlockExpr | semmle.order | 1 | +| test.rs:66:17:66:17 | LiteralExpr | test.rs:66:13:66:17 | BinaryExpr | semmle.label | | +| test.rs:66:17:66:17 | LiteralExpr | test.rs:66:13:66:17 | BinaryExpr | semmle.order | 1 | +| test.rs:70:5:76:5 | enter test_if_let_else | test.rs:71:12:71:26 | LetExpr | semmle.label | | +| test.rs:70:5:76:5 | enter test_if_let_else | test.rs:71:12:71:26 | LetExpr | semmle.order | 1 | +| test.rs:70:5:76:5 | exit test_if_let_else (normal) | test.rs:70:5:76:5 | exit test_if_let_else | semmle.label | | +| test.rs:70:5:76:5 | exit test_if_let_else (normal) | test.rs:70:5:76:5 | exit test_if_let_else | semmle.order | 1 | +| test.rs:70:48:76:5 | BlockExpr | test.rs:70:5:76:5 | exit test_if_let_else (normal) | semmle.label | | +| test.rs:70:48:76:5 | BlockExpr | test.rs:70:5:76:5 | exit test_if_let_else (normal) | semmle.order | 1 | +| test.rs:71:9:75:9 | IfExpr | test.rs:70:48:76:5 | BlockExpr | semmle.label | | +| test.rs:71:9:75:9 | IfExpr | test.rs:70:48:76:5 | BlockExpr | semmle.order | 1 | +| test.rs:71:12:71:26 | LetExpr | test.rs:71:16:71:22 | TupleStructPat | semmle.label | | +| test.rs:71:12:71:26 | LetExpr | test.rs:71:16:71:22 | TupleStructPat | semmle.order | 1 | +| test.rs:71:16:71:22 | TupleStructPat | test.rs:72:13:72:13 | PathExpr | semmle.label | match | +| test.rs:71:16:71:22 | TupleStructPat | test.rs:72:13:72:13 | PathExpr | semmle.order | 1 | +| test.rs:71:16:71:22 | TupleStructPat | test.rs:74:13:74:13 | LiteralExpr | semmle.label | no-match | +| test.rs:71:16:71:22 | TupleStructPat | test.rs:74:13:74:13 | LiteralExpr | semmle.order | 2 | +| test.rs:71:28:73:9 | BlockExpr | test.rs:71:9:75:9 | IfExpr | semmle.label | | +| test.rs:71:28:73:9 | BlockExpr | test.rs:71:9:75:9 | IfExpr | semmle.order | 1 | +| test.rs:72:13:72:13 | PathExpr | test.rs:71:28:73:9 | BlockExpr | semmle.label | | +| test.rs:72:13:72:13 | PathExpr | test.rs:71:28:73:9 | BlockExpr | semmle.order | 1 | +| test.rs:73:16:75:9 | BlockExpr | test.rs:71:9:75:9 | IfExpr | semmle.label | | +| test.rs:73:16:75:9 | BlockExpr | test.rs:71:9:75:9 | IfExpr | semmle.order | 1 | +| test.rs:74:13:74:13 | LiteralExpr | test.rs:73:16:75:9 | BlockExpr | semmle.label | | +| test.rs:74:13:74:13 | LiteralExpr | test.rs:73:16:75:9 | BlockExpr | semmle.order | 1 | +| test.rs:78:5:83:5 | enter test_if_let | test.rs:79:9:81:9 | ExprStmt | semmle.label | | +| test.rs:78:5:83:5 | enter test_if_let | test.rs:79:9:81:9 | ExprStmt | semmle.order | 1 | +| test.rs:78:5:83:5 | exit test_if_let (normal) | test.rs:78:5:83:5 | exit test_if_let | semmle.label | | +| test.rs:78:5:83:5 | exit test_if_let (normal) | test.rs:78:5:83:5 | exit test_if_let | semmle.order | 1 | +| test.rs:78:43:83:5 | BlockExpr | test.rs:78:5:83:5 | exit test_if_let (normal) | semmle.label | | +| test.rs:78:43:83:5 | BlockExpr | test.rs:78:5:83:5 | exit test_if_let (normal) | semmle.order | 1 | +| test.rs:79:9:81:9 | ExprStmt | test.rs:79:12:79:26 | LetExpr | semmle.label | | +| test.rs:79:9:81:9 | ExprStmt | test.rs:79:12:79:26 | LetExpr | semmle.order | 1 | +| test.rs:79:9:81:9 | IfExpr | test.rs:82:9:82:9 | LiteralExpr | semmle.label | | +| test.rs:79:9:81:9 | IfExpr | test.rs:82:9:82:9 | LiteralExpr | semmle.order | 1 | +| test.rs:79:12:79:26 | LetExpr | test.rs:79:16:79:22 | TupleStructPat | semmle.label | | +| test.rs:79:12:79:26 | LetExpr | test.rs:79:16:79:22 | TupleStructPat | semmle.order | 1 | +| test.rs:79:16:79:22 | TupleStructPat | test.rs:79:9:81:9 | IfExpr | semmle.label | no-match | +| test.rs:79:16:79:22 | TupleStructPat | test.rs:79:9:81:9 | IfExpr | semmle.order | 1 | +| test.rs:79:16:79:22 | TupleStructPat | test.rs:80:13:80:13 | PathExpr | semmle.label | match | +| test.rs:79:16:79:22 | TupleStructPat | test.rs:80:13:80:13 | PathExpr | semmle.order | 2 | +| test.rs:79:28:81:9 | BlockExpr | test.rs:79:9:81:9 | IfExpr | semmle.label | | +| test.rs:79:28:81:9 | BlockExpr | test.rs:79:9:81:9 | IfExpr | semmle.order | 1 | +| test.rs:80:13:80:13 | PathExpr | test.rs:79:28:81:9 | BlockExpr | semmle.label | | +| test.rs:80:13:80:13 | PathExpr | test.rs:79:28:81:9 | BlockExpr | semmle.order | 1 | +| test.rs:82:9:82:9 | LiteralExpr | test.rs:78:43:83:5 | BlockExpr | semmle.label | | +| test.rs:82:9:82:9 | LiteralExpr | test.rs:78:43:83:5 | BlockExpr | semmle.order | 1 | +| test.rs:105:5:108:5 | enter test_and_operator | test.rs:106:9:106:28 | LetStmt | semmle.label | | +| test.rs:105:5:108:5 | enter test_and_operator | test.rs:106:9:106:28 | LetStmt | semmle.order | 1 | +| test.rs:105:5:108:5 | exit test_and_operator (normal) | test.rs:105:5:108:5 | exit test_and_operator | semmle.label | | +| test.rs:105:5:108:5 | exit test_and_operator (normal) | test.rs:105:5:108:5 | exit test_and_operator | semmle.order | 1 | +| test.rs:105:61:108:5 | BlockExpr | test.rs:105:5:108:5 | exit test_and_operator (normal) | semmle.label | | +| test.rs:105:61:108:5 | BlockExpr | test.rs:105:5:108:5 | exit test_and_operator (normal) | semmle.order | 1 | +| test.rs:106:9:106:28 | LetStmt | test.rs:106:17:106:27 | BinaryExpr | semmle.label | | +| test.rs:106:9:106:28 | LetStmt | test.rs:106:17:106:27 | BinaryExpr | semmle.order | 1 | +| test.rs:106:13:106:13 | IdentPat | test.rs:107:9:107:9 | PathExpr | semmle.label | match, no-match | +| test.rs:106:13:106:13 | IdentPat | test.rs:107:9:107:9 | PathExpr | semmle.order | 1 | +| test.rs:106:13:106:13 | IdentPat | test.rs:107:9:107:9 | PathExpr | semmle.order | 2 | +| test.rs:106:17:106:17 | PathExpr | test.rs:106:13:106:13 | IdentPat | semmle.label | false | +| test.rs:106:17:106:17 | PathExpr | test.rs:106:13:106:13 | IdentPat | semmle.order | 1 | +| test.rs:106:17:106:17 | PathExpr | test.rs:106:22:106:22 | PathExpr | semmle.label | true | +| test.rs:106:17:106:17 | PathExpr | test.rs:106:22:106:22 | PathExpr | semmle.order | 2 | +| test.rs:106:17:106:22 | BinaryExpr | test.rs:106:17:106:17 | PathExpr | semmle.label | | +| test.rs:106:17:106:22 | BinaryExpr | test.rs:106:17:106:17 | PathExpr | semmle.order | 1 | +| test.rs:106:17:106:27 | BinaryExpr | test.rs:106:17:106:22 | BinaryExpr | semmle.label | | +| test.rs:106:17:106:27 | BinaryExpr | test.rs:106:17:106:22 | BinaryExpr | semmle.order | 1 | +| test.rs:106:22:106:22 | PathExpr | test.rs:106:13:106:13 | IdentPat | semmle.label | false | +| test.rs:106:22:106:22 | PathExpr | test.rs:106:13:106:13 | IdentPat | semmle.order | 1 | +| test.rs:106:22:106:22 | PathExpr | test.rs:106:27:106:27 | PathExpr | semmle.label | true | +| test.rs:106:22:106:22 | PathExpr | test.rs:106:27:106:27 | PathExpr | semmle.order | 2 | +| test.rs:106:27:106:27 | PathExpr | test.rs:106:13:106:13 | IdentPat | semmle.label | | +| test.rs:106:27:106:27 | PathExpr | test.rs:106:13:106:13 | IdentPat | semmle.order | 1 | +| test.rs:107:9:107:9 | PathExpr | test.rs:105:61:108:5 | BlockExpr | semmle.label | | +| test.rs:107:9:107:9 | PathExpr | test.rs:105:61:108:5 | BlockExpr | semmle.order | 1 | +| test.rs:110:5:113:5 | enter test_or_operator | test.rs:111:9:111:28 | LetStmt | semmle.label | | +| test.rs:110:5:113:5 | enter test_or_operator | test.rs:111:9:111:28 | LetStmt | semmle.order | 1 | +| test.rs:110:5:113:5 | exit test_or_operator (normal) | test.rs:110:5:113:5 | exit test_or_operator | semmle.label | | +| test.rs:110:5:113:5 | exit test_or_operator (normal) | test.rs:110:5:113:5 | exit test_or_operator | semmle.order | 1 | +| test.rs:110:60:113:5 | BlockExpr | test.rs:110:5:113:5 | exit test_or_operator (normal) | semmle.label | | +| test.rs:110:60:113:5 | BlockExpr | test.rs:110:5:113:5 | exit test_or_operator (normal) | semmle.order | 1 | +| test.rs:111:9:111:28 | LetStmt | test.rs:111:17:111:27 | BinaryExpr | semmle.label | | +| test.rs:111:9:111:28 | LetStmt | test.rs:111:17:111:27 | BinaryExpr | semmle.order | 1 | +| test.rs:111:13:111:13 | IdentPat | test.rs:112:9:112:9 | PathExpr | semmle.label | match, no-match | +| test.rs:111:13:111:13 | IdentPat | test.rs:112:9:112:9 | PathExpr | semmle.order | 1 | +| test.rs:111:13:111:13 | IdentPat | test.rs:112:9:112:9 | PathExpr | semmle.order | 2 | +| test.rs:111:17:111:17 | PathExpr | test.rs:111:13:111:13 | IdentPat | semmle.label | true | +| test.rs:111:17:111:17 | PathExpr | test.rs:111:13:111:13 | IdentPat | semmle.order | 1 | +| test.rs:111:17:111:17 | PathExpr | test.rs:111:22:111:22 | PathExpr | semmle.label | false | +| test.rs:111:17:111:17 | PathExpr | test.rs:111:22:111:22 | PathExpr | semmle.order | 2 | +| test.rs:111:17:111:22 | BinaryExpr | test.rs:111:17:111:17 | PathExpr | semmle.label | | +| test.rs:111:17:111:22 | BinaryExpr | test.rs:111:17:111:17 | PathExpr | semmle.order | 1 | +| test.rs:111:17:111:27 | BinaryExpr | test.rs:111:17:111:22 | BinaryExpr | semmle.label | | +| test.rs:111:17:111:27 | BinaryExpr | test.rs:111:17:111:22 | BinaryExpr | semmle.order | 1 | +| test.rs:111:22:111:22 | PathExpr | test.rs:111:13:111:13 | IdentPat | semmle.label | true | +| test.rs:111:22:111:22 | PathExpr | test.rs:111:13:111:13 | IdentPat | semmle.order | 1 | +| test.rs:111:22:111:22 | PathExpr | test.rs:111:27:111:27 | PathExpr | semmle.label | false | +| test.rs:111:22:111:22 | PathExpr | test.rs:111:27:111:27 | PathExpr | semmle.order | 2 | +| test.rs:111:27:111:27 | PathExpr | test.rs:111:13:111:13 | IdentPat | semmle.label | | +| test.rs:111:27:111:27 | PathExpr | test.rs:111:13:111:13 | IdentPat | semmle.order | 1 | +| test.rs:112:9:112:9 | PathExpr | test.rs:110:60:113:5 | BlockExpr | semmle.label | | +| test.rs:112:9:112:9 | PathExpr | test.rs:110:60:113:5 | BlockExpr | semmle.order | 1 | +| test.rs:115:5:118:5 | enter test_or_operator_2 | test.rs:116:9:116:36 | LetStmt | semmle.label | | +| test.rs:115:5:118:5 | enter test_or_operator_2 | test.rs:116:9:116:36 | LetStmt | semmle.order | 1 | +| test.rs:115:5:118:5 | exit test_or_operator_2 (normal) | test.rs:115:5:118:5 | exit test_or_operator_2 | semmle.label | | +| test.rs:115:5:118:5 | exit test_or_operator_2 (normal) | test.rs:115:5:118:5 | exit test_or_operator_2 | semmle.order | 1 | +| test.rs:115:61:118:5 | BlockExpr | test.rs:115:5:118:5 | exit test_or_operator_2 (normal) | semmle.label | | +| test.rs:115:61:118:5 | BlockExpr | test.rs:115:5:118:5 | exit test_or_operator_2 (normal) | semmle.order | 1 | +| test.rs:116:9:116:36 | LetStmt | test.rs:116:17:116:35 | BinaryExpr | semmle.label | | +| test.rs:116:9:116:36 | LetStmt | test.rs:116:17:116:35 | BinaryExpr | semmle.order | 1 | +| test.rs:116:13:116:13 | IdentPat | test.rs:117:9:117:9 | PathExpr | semmle.label | match, no-match | +| test.rs:116:13:116:13 | IdentPat | test.rs:117:9:117:9 | PathExpr | semmle.order | 1 | +| test.rs:116:13:116:13 | IdentPat | test.rs:117:9:117:9 | PathExpr | semmle.order | 2 | +| test.rs:116:17:116:17 | PathExpr | test.rs:116:13:116:13 | IdentPat | semmle.label | true | +| test.rs:116:17:116:17 | PathExpr | test.rs:116:13:116:13 | IdentPat | semmle.order | 1 | +| test.rs:116:17:116:30 | BinaryExpr | test.rs:116:17:116:17 | PathExpr | semmle.label | | +| test.rs:116:17:116:30 | BinaryExpr | test.rs:116:17:116:17 | PathExpr | semmle.order | 1 | +| test.rs:116:17:116:35 | BinaryExpr | test.rs:116:17:116:30 | BinaryExpr | semmle.label | | +| test.rs:116:17:116:35 | BinaryExpr | test.rs:116:17:116:30 | BinaryExpr | semmle.order | 1 | +| test.rs:117:9:117:9 | PathExpr | test.rs:115:61:118:5 | BlockExpr | semmle.label | | +| test.rs:117:9:117:9 | PathExpr | test.rs:115:61:118:5 | BlockExpr | semmle.order | 1 | +| test.rs:122:1:128:1 | enter test_match | test.rs:123:11:123:21 | PathExpr | semmle.label | | +| test.rs:122:1:128:1 | enter test_match | test.rs:123:11:123:21 | PathExpr | semmle.order | 1 | +| test.rs:122:1:128:1 | exit test_match (normal) | test.rs:122:1:128:1 | exit test_match | semmle.label | | +| test.rs:122:1:128:1 | exit test_match (normal) | test.rs:122:1:128:1 | exit test_match | semmle.order | 1 | +| test.rs:122:44:128:1 | BlockExpr | test.rs:122:1:128:1 | exit test_match (normal) | semmle.label | | +| test.rs:122:44:128:1 | BlockExpr | test.rs:122:1:128:1 | exit test_match (normal) | semmle.order | 1 | +| test.rs:123:5:127:5 | MatchExpr | test.rs:122:44:128:1 | BlockExpr | semmle.label | | +| test.rs:123:5:127:5 | MatchExpr | test.rs:122:44:128:1 | BlockExpr | semmle.order | 1 | +| test.rs:123:11:123:21 | PathExpr | test.rs:124:9:124:23 | TupleStructPat | semmle.label | | +| test.rs:123:11:123:21 | PathExpr | test.rs:124:9:124:23 | TupleStructPat | semmle.order | 1 | +| test.rs:124:9:124:23 | TupleStructPat | test.rs:123:5:127:5 | MatchExpr | semmle.label | no-match | +| test.rs:124:9:124:23 | TupleStructPat | test.rs:123:5:127:5 | MatchExpr | semmle.order | 1 | +| test.rs:124:9:124:23 | TupleStructPat | test.rs:124:28:124:28 | PathExpr | semmle.label | match | +| test.rs:124:9:124:23 | TupleStructPat | test.rs:124:28:124:28 | PathExpr | semmle.order | 2 | +| test.rs:124:9:124:23 | TupleStructPat | test.rs:125:9:125:23 | TupleStructPat | semmle.label | no-match | +| test.rs:124:9:124:23 | TupleStructPat | test.rs:125:9:125:23 | TupleStructPat | semmle.order | 3 | +| test.rs:124:28:124:28 | PathExpr | test.rs:124:32:124:33 | LiteralExpr | semmle.label | | +| test.rs:124:28:124:28 | PathExpr | test.rs:124:32:124:33 | LiteralExpr | semmle.order | 1 | +| test.rs:124:32:124:33 | LiteralExpr | test.rs:124:28:124:33 | BinaryExpr | semmle.label | | +| test.rs:124:32:124:33 | LiteralExpr | test.rs:124:28:124:33 | BinaryExpr | semmle.order | 1 | +| test.rs:125:9:125:23 | TupleStructPat | test.rs:123:5:127:5 | MatchExpr | semmle.label | no-match | +| test.rs:125:9:125:23 | TupleStructPat | test.rs:123:5:127:5 | MatchExpr | semmle.order | 1 | +| test.rs:125:9:125:23 | TupleStructPat | test.rs:125:28:125:28 | PathExpr | semmle.label | match | +| test.rs:125:9:125:23 | TupleStructPat | test.rs:125:28:125:28 | PathExpr | semmle.order | 2 | +| test.rs:125:9:125:23 | TupleStructPat | test.rs:126:9:126:20 | PathPat | semmle.label | no-match | +| test.rs:125:9:125:23 | TupleStructPat | test.rs:126:9:126:20 | PathPat | semmle.order | 3 | +| test.rs:125:28:125:28 | PathExpr | test.rs:123:5:127:5 | MatchExpr | semmle.label | | +| test.rs:125:28:125:28 | PathExpr | test.rs:123:5:127:5 | MatchExpr | semmle.order | 1 | +| test.rs:126:9:126:20 | PathPat | test.rs:123:5:127:5 | MatchExpr | semmle.label | no-match | +| test.rs:126:9:126:20 | PathPat | test.rs:123:5:127:5 | MatchExpr | semmle.order | 1 | +| test.rs:126:9:126:20 | PathPat | test.rs:126:25:126:25 | LiteralExpr | semmle.label | match | +| test.rs:126:9:126:20 | PathPat | test.rs:126:25:126:25 | LiteralExpr | semmle.order | 2 | +| test.rs:126:25:126:25 | LiteralExpr | test.rs:123:5:127:5 | MatchExpr | semmle.label | | +| test.rs:126:25:126:25 | LiteralExpr | test.rs:123:5:127:5 | MatchExpr | semmle.order | 1 | +| test.rs:131:5:136:5 | enter test_infinite_loop | test.rs:132:9:134:9 | ExprStmt | semmle.label | | +| test.rs:131:5:136:5 | enter test_infinite_loop | test.rs:132:9:134:9 | ExprStmt | semmle.order | 1 | +| test.rs:132:9:134:9 | ExprStmt | test.rs:133:13:133:13 | LiteralExpr | semmle.label | | +| test.rs:132:9:134:9 | ExprStmt | test.rs:133:13:133:13 | LiteralExpr | semmle.order | 1 | +| test.rs:132:14:134:9 | BlockExpr | test.rs:133:13:133:13 | LiteralExpr | semmle.label | | +| test.rs:132:14:134:9 | BlockExpr | test.rs:133:13:133:13 | LiteralExpr | semmle.order | 1 | +| test.rs:133:13:133:13 | LiteralExpr | test.rs:132:14:134:9 | BlockExpr | semmle.label | | +| test.rs:133:13:133:13 | LiteralExpr | test.rs:132:14:134:9 | BlockExpr | semmle.order | 1 | +| test.rs:138:5:143:5 | enter test_let_match | test.rs:139:9:141:10 | LetStmt | semmle.label | | +| test.rs:138:5:143:5 | enter test_let_match | test.rs:139:9:141:10 | LetStmt | semmle.order | 1 | +| test.rs:138:5:143:5 | exit test_let_match (normal) | test.rs:138:5:143:5 | exit test_let_match | semmle.label | | +| test.rs:138:5:143:5 | exit test_let_match (normal) | test.rs:138:5:143:5 | exit test_let_match | semmle.order | 1 | +| test.rs:138:39:143:5 | BlockExpr | test.rs:138:5:143:5 | exit test_let_match (normal) | semmle.label | | +| test.rs:138:39:143:5 | BlockExpr | test.rs:138:5:143:5 | exit test_let_match (normal) | semmle.order | 1 | +| test.rs:139:9:141:10 | LetStmt | test.rs:139:23:139:23 | PathExpr | semmle.label | | +| test.rs:139:9:141:10 | LetStmt | test.rs:139:23:139:23 | PathExpr | semmle.order | 1 | +| test.rs:139:13:139:19 | TupleStructPat | test.rs:140:13:140:27 | LiteralExpr | semmle.label | no-match | +| test.rs:139:13:139:19 | TupleStructPat | test.rs:140:13:140:27 | LiteralExpr | semmle.order | 1 | +| test.rs:139:13:139:19 | TupleStructPat | test.rs:142:9:142:9 | PathExpr | semmle.label | match | +| test.rs:139:13:139:19 | TupleStructPat | test.rs:142:9:142:9 | PathExpr | semmle.order | 2 | +| test.rs:139:23:139:23 | PathExpr | test.rs:139:13:139:19 | TupleStructPat | semmle.label | | +| test.rs:139:23:139:23 | PathExpr | test.rs:139:13:139:19 | TupleStructPat | semmle.order | 1 | +| test.rs:140:13:140:27 | LiteralExpr | test.rs:139:30:141:9 | BlockExpr | semmle.label | | +| test.rs:140:13:140:27 | LiteralExpr | test.rs:139:30:141:9 | BlockExpr | semmle.order | 1 | +| test.rs:142:9:142:9 | PathExpr | test.rs:138:39:143:5 | BlockExpr | semmle.label | | +| test.rs:142:9:142:9 | PathExpr | test.rs:138:39:143:5 | BlockExpr | semmle.order | 1 | diff --git a/rust/ql/test/library-tests/controlflow/test.rs b/rust/ql/test/library-tests/controlflow/test.rs index f60a227c16c8..fc7bd9c6c277 100644 --- a/rust/ql/test/library-tests/controlflow/test.rs +++ b/rust/ql/test/library-tests/controlflow/test.rs @@ -1,16 +1,144 @@ -fn main() -> i64 { - if "foo" == "bar" { - decrement(0) - } else { - decrement(5) +fn test_call() -> bool { + test_and_operator(true, false, true); + foo::(42); +} + +mod loop_expression { + + fn test_break_and_continue(n: i64) -> bool { + let mut i = n; + loop { + i = next(i); + if i > 10000 { + return false; + } + if i == 1 { + break; + } + if i % 2 != 0 { + continue; + } + i = i / 2 + } + return true; + } + + fn test_break_with_labels() -> bool { + 'outer: loop { + 'inner: loop { + if false { + break; + } else if true { + break 'outer; + } + break 'inner; + } + } + true } + + fn test_continue_with_labels() -> ! { + 'outer: loop { + 1; + 'inner: loop { + if false { + continue; + } else if true { + continue 'outer; + } + continue 'inner; + } + } + } +} + +fn test_nested_function(n: i64) -> i64 { + let add_one = |i| i + 1; + add_one(add_one(n)) } -fn decrement(n: i64) -> i64 { - 12; - if n == 0 { +mod if_expression { + + fn test_if_else(n: i64) -> i64 { + if n <= 0 { + 0 + } else { + n - 1 + } + } + + fn test_if_let_else(a: Option) -> i64 { + if let Some(n) = a { + n + } else { + 0 + } + } + + fn test_if_let(a: Option) -> i64 { + if let Some(n) = a { + n + } 0 - } else { - n - 1 + } + + fn test_nested_if(a: i64) -> i64 { + if (if a < 0 { a < -10 } else { a > 10}) { + 1 + } else { + 0 + } + } + + fn test_nested_if_match(a: i64) -> i64 { + if (match a { 0 => true, _ => false }) { + 1 + } else { + 0 + } + } + +} + +mod logical_operators { + + fn test_and_operator(a: bool, b: bool, c: bool) -> bool { + let d = a && b && c; + d + } + + fn test_or_operator(a: bool, b: bool, c: bool) -> bool { + let d = a || b || c; + d + } + + fn test_or_operator_2(a: bool, b: i64, c: bool) -> bool { + let d = a || (b == 28) || c; + d + } + +} + +fn test_match(maybe_digit: Option) -> { + match maybe_digit { + Option::Some(x) if x < 10 => x + 5, + Option::Some(x) => x, + Option::None => 5, + } +} + +mod divergence { + fn test_infinite_loop() -> &'static str { + loop { + 1 + } + "never reached" + } + + fn test_let_match(a: Option) { + let Some(n) = a else { + "Expected some" + }; + n } }