Merge pull request #18820 from paldepind/rust-fewer-no-match

Rust: Remove nonsentical no-match CFG edges
This commit is contained in:
Simon Friis Vindum
2025-02-21 14:18:23 +01:00
committed by GitHub
12 changed files with 1358 additions and 823 deletions

View File

@@ -349,7 +349,6 @@ lib/codeql/rust/elements/internal/ParenPatConstructor.qll 9aea3c3b677755177d85c6
lib/codeql/rust/elements/internal/ParenTypeReprConstructor.qll b3825399f90c8546c254df1f3285fe6053b8137e4705978de50017be941c9f42 696fa20ce5bd4731566b88c8ea13df836627354d37cc9d39514d89d8fb730200
lib/codeql/rust/elements/internal/ParenthesizedArgListConstructor.qll 67f49d376e87a58d7b22eb6e8f90c5b3d295a732be657b27ea6b86835a0ac327 6549e4f5bccb2d29dfeb207625f4d940344ac1bb4c7a7ae007a8eb1c4c985da0
lib/codeql/rust/elements/internal/ParenthesizedArgListImpl.qll 16ded8aee2e245110c97456a3151045bae48db3990ac2ed0940422f26b1596fe 207720c3403ed8fe9725e860e0ed3aa3b7fb257cbc2478414731080001c6aaef
lib/codeql/rust/elements/internal/PatImpl.qll 37c9b1da7aa625117644e2cd74ec0b174f69a38cf66926add01786a05d5ad2ad 143685a0b4873fa0b73b204285dca956e59b32d527bfac6cc336326d244994b7
lib/codeql/rust/elements/internal/PathAstNodeImpl.qll 5a38c42a9127fc2071a9e8f0914996d8c3763e2708805de922e42771de50f649 ebe319cce565497071118cd4c291668bbcdf5fc8942c07efc5a10181b4ce5880
lib/codeql/rust/elements/internal/PathConstructor.qll 5c6354c28faf9f28f3efee8e19bdb82773adcf4b0c1a38788b06af25bcb6bc4a 3e2aeef7b6b9cda7f7f45a6c8119c98803aa644cf6a492cf0fce318eba40fe8f
lib/codeql/rust/elements/internal/PathExprBaseImpl.qll e8b09447ee41b4123f7d94c6b366b2602d8022c9644f1088c670c7794307ab2e 96b9b328771aaf19ba18d0591e85fcc915c0f930b2479b433de3bfdd2ea25249

1
rust/ql/.gitattributes generated vendored
View File

@@ -351,7 +351,6 @@
/lib/codeql/rust/elements/internal/ParenTypeReprConstructor.qll linguist-generated
/lib/codeql/rust/elements/internal/ParenthesizedArgListConstructor.qll linguist-generated
/lib/codeql/rust/elements/internal/ParenthesizedArgListImpl.qll linguist-generated
/lib/codeql/rust/elements/internal/PatImpl.qll linguist-generated
/lib/codeql/rust/elements/internal/PathAstNodeImpl.qll linguist-generated
/lib/codeql/rust/elements/internal/PathConstructor.qll linguist-generated
/lib/codeql/rust/elements/internal/PathExprBaseImpl.qll linguist-generated

View File

@@ -117,51 +117,57 @@ class BooleanCompletion extends ConditionalCompletion, TBooleanCompletion {
override string toString() { result = "boolean(" + value + ")" }
}
/** Holds if `pat` is guaranteed to match at the point in the AST where it occurs. */
pragma[nomagic]
private predicate isExhaustiveMatch(Pat pat) {
(
pat instanceof WildcardPat
or
pat = any(IdentPat ip | not ip.hasPat() and ip = any(Variable v).getPat())
or
pat instanceof RestPat
or
// `let` statements without an `else` branch must be exhaustive
pat = any(LetStmt let | not let.hasLetElse()).getPat()
or
// `match` expressions must be exhaustive, so last arm cannot fail
pat = any(MatchExpr me).getLastArm().getPat()
or
// macro invocations are exhaustive if their expansion is
pat = any(MacroPat mp | isExhaustiveMatch(mp.getMacroCall().getExpanded()))
or
// parameter patterns must be exhaustive
pat = any(Param p).getPat()
) and
not pat = any(ForExpr for).getPat() // workaround until `for` loops are desugared
/**
* Holds if `pat` can not _itself_ be the cause of a pattern match failure. This
* does not mean that `pat` is irrefutable, as its children might be the cause
* of a failure.
*/
private predicate cannotCauseMatchFailure(Pat pat) {
pat instanceof RangePat or
// Identifier patterns that are in fact path patterns can cause failures. For
// instance `None`. Only if an `@ ...` part is present can we be sure that
// it's an actual identifier pattern.
pat = any(IdentPat p | p.hasPat()) or
pat instanceof WildcardPat or
pat instanceof RestPat or
pat instanceof RefPat or
pat instanceof TuplePat or
pat instanceof MacroPat
}
/**
* Holds if `pat` is guaranteed to match at the point in the AST where it occurs
* due to Rust's exhaustiveness checks.
*/
private predicate guaranteedMatchPosition(Pat pat) {
// `let` statements without an `else` branch must match
pat = any(LetStmt let | not let.hasLetElse()).getPat()
or
exists(Pat parent | isExhaustiveMatch(parent) |
pat = parent.(BoxPat).getPat()
// `match` expressions must be exhaustive, so last arm must match
pat = any(MatchExpr me).getLastArm().getPat()
or
// parameter patterns must match
pat = any(Param p).getPat()
or
exists(Pat parent | guaranteedMatchPosition(parent) |
// propagate to all children except for or patterns
parent = pat.getParentPat() and not parent instanceof OrPat
or
pat = parent.(IdentPat).getPat()
// for or patterns only the last child inherits the property
parent.(OrPat).getLastPat() = pat
or
pat = parent.(MacroPat).getMacroCall().getExpanded()
or
pat = parent.(ParenPat).getPat()
or
pat = parent.(RecordPat).getRecordPatFieldList().getField(_).getPat()
or
pat = parent.(RefPat).getPat()
or
pat = parent.(TuplePat).getAField()
or
pat = parent.(TupleStructPat).getAField()
or
pat = parent.(OrPat).getLastPat()
// for macro patterns we propagate to the expanded pattern
parent.(MacroPat).getMacroCall().getExpanded() = pat
)
}
private predicate guaranteedMatch(Pat pat) {
(cannotCauseMatchFailure(pat) or guaranteedMatchPosition(pat)) and
// In `for` loops we use a no-match edge from the pattern to terminate the
// loop, hence we special case and always allow the no-match edge.
not pat = any(ForExpr for).getPat()
}
/**
* A completion that represents the result of a pattern match.
*/
@@ -170,7 +176,7 @@ class MatchCompletion extends TMatchCompletion, ConditionalCompletion {
override predicate isValidForSpecific(AstNode e) {
e instanceof Pat and
if isExhaustiveMatch(e) then value = true else any()
if guaranteedMatch(e) then value = true else any()
or
e instanceof TryExpr and value = true
}

View File

@@ -641,7 +641,7 @@ module PatternTrees {
super.last(node, c)
or
c.(MatchCompletion).failed() and
completionIsValidFor(c, this) and
completionIsValidFor(c, node) and
(node = this or last(this.getPatRanked(_), node, c))
}
}

View File

@@ -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 `Pat`.
*
@@ -6,14 +5,25 @@
*/
private import codeql.rust.elements.internal.generated.Pat
private import codeql.rust.elements.internal.generated.ParentChild
/**
* INTERNAL: This module contains the customizable definition of `Pat` and should not
* be referenced directly.
*/
module Impl {
// the following QLdoc is generated: if you need to edit it, do it in the schema file
/**
* The base class for patterns.
*/
class Pat extends Generated::Pat { }
class Pat extends Generated::Pat {
/**
* Gets the pattern under which this pattern is immediately nested, if any.
*/
Pat getParentPat() {
result = getImmediateParent(this)
or
result.(RecordPat).getRecordPatFieldList().getAField().getPat() = this
}
}
}

View File

@@ -36,15 +36,9 @@ module Impl {
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) |
exists(Pat p0 | result = p0.getParentPat() |
p0 = p
or
p0 = getAPatAncestor(p) and
@@ -222,7 +216,7 @@ module Impl {
or
exists(Pat mid |
mid = getAVariablePatAncestor(v) and
result = getImmediatePatParent(mid)
result = mid.getParentPat()
)
}

View File

@@ -19,6 +19,7 @@ edges
| test.rs:6:17:6:31 | let ... = b | test.rs:6:31:6:31 | b | |
| test.rs:6:21:6:27 | Some(...) | test.rs:6:12:6:31 | [boolean(false)] ... && ... | no-match |
| test.rs:6:21:6:27 | Some(...) | test.rs:6:26:6:26 | d | match |
| test.rs:6:26:6:26 | d | test.rs:6:12:6:31 | [boolean(false)] ... && ... | no-match |
| test.rs:6:26:6:26 | d | test.rs:6:12:6:31 | [boolean(true)] ... && ... | match |
| test.rs:6:26:6:26 | d | test.rs:6:26:6:26 | d | |
| test.rs:6:31:6:31 | b | test.rs:6:21:6:27 | Some(...) | |
@@ -46,6 +47,7 @@ edges
| test.rs:14:12:15:16 | [boolean(false)] ... && ... | test.rs:19:13:19:17 | false | false |
| test.rs:14:12:15:16 | [boolean(true)] ... && ... | test.rs:17:13:17:13 | d | true |
| test.rs:14:17:14:25 | let ... = b | test.rs:14:25:14:25 | b | |
| test.rs:14:21:14:21 | d | test.rs:14:12:14:25 | [boolean(false)] ... && ... | no-match |
| test.rs:14:21:14:21 | d | test.rs:14:12:14:25 | [boolean(true)] ... && ... | match |
| test.rs:14:21:14:21 | d | test.rs:14:21:14:21 | d | |
| test.rs:14:25:14:25 | b | test.rs:14:21:14:21 | d | |

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,7 @@
deadEnd
| test.rs:455:13:455:25 | one_or_two!... |
multipleSuccessors
| test.rs:455:13:455:25 | [match(false)] 1 \| 2 | no-match | test.rs:455:13:455:25 | one_or_two!... |
| test.rs:455:13:455:25 | [match(false)] 1 \| 2 | no-match | test.rs:456:13:456:13 | _ |
| test.rs:455:13:455:25 | [match(true)] 1 \| 2 | match | test.rs:455:13:455:25 | one_or_two!... |
| test.rs:455:13:455:25 | [match(true)] 1 \| 2 | match | test.rs:455:30:455:30 | 3 |

File diff suppressed because it is too large Load Diff

View File

@@ -380,7 +380,9 @@ mod patterns {
return;
}
struct MyStruct {}
struct MyStruct {
x: i64
}
fn empty_struct_pattern(st: MyStruct) -> i64 {
match st {
@@ -388,6 +390,13 @@ mod patterns {
}
}
fn struct_pattern(st: MyStruct) -> i64 {
match st {
MyStruct { x: 1 } => 0,
MyStruct { x } => 3,
}
}
fn range_pattern() -> i64 {
match 42 {
..0 => 1,
@@ -412,6 +421,64 @@ mod patterns {
};
a
}
fn tuple_pattern(a: i64, b: i64) -> i64 {
match (a, b) {
(1, _) => 2,
(.., 2) => 3,
(..) => 4,
}
}
fn or_pattern(a: i64) -> i64 {
match a {
0 | 1 | 2 => 3,
_ => 4,
}
}
fn or_pattern_2(a: Option<bool>) -> i64 {
match a {
None => 3,
Some(true) | Some(false) => 4,
}
}
macro_rules! one_or_two {
() => {
1 | 2
};
}
fn or_pattern_3(a: i64) -> i64 {
match a {
one_or_two!() => 3,
_ => 4,
}
}
fn irrefutable_pattern_and_dead_code(pair: &(i64, MyStruct)) -> i64 {
match pair {
&(n, MyStruct { x: _ }) => n,
_ => 0, // dead code
}
}
enum MyEnum {
StructVariant { n: i64 },
TupleVariant(i64),
UnitVariant,
}
use MyEnum::*;
fn enum_pattern(e: MyEnum) -> i64 {
match e {
StructVariant { n: _ } => 0,
TupleVariant(_) => 1,
UnitVariant => 2,
}
}
}
mod divergence {

View File

@@ -221,6 +221,7 @@ edges
| main.rs:87:8:88:12 | let ... = s1 | main.rs:88:11:88:12 | s1 | |
| main.rs:87:12:87:23 | Some(...) | main.rs:87:5:90:5 | if ... {...} | no-match |
| main.rs:87:12:87:23 | Some(...) | main.rs:87:21:87:22 | s2 | match |
| main.rs:87:17:87:22 | ref s2 | main.rs:87:5:90:5 | if ... {...} | no-match |
| main.rs:87:17:87:22 | ref s2 | main.rs:89:9:89:22 | ExprStmt | match |
| main.rs:87:21:87:22 | s2 | main.rs:87:17:87:22 | ref s2 | |
| main.rs:88:11:88:12 | s1 | main.rs:87:12:87:23 | Some(...) | |
@@ -236,6 +237,7 @@ edges
| main.rs:94:9:94:16 | Some(...) | main.rs:94:14:94:15 | x5 | match |
| main.rs:94:9:94:16 | Some(...) | main.rs:96:13:96:19 | MacroStmts | no-match |
| main.rs:94:14:94:15 | x5 | main.rs:94:14:94:15 | x5 | |
| main.rs:94:14:94:15 | x5 | main.rs:96:13:96:19 | MacroStmts | no-match |
| main.rs:94:14:94:15 | x5 | main.rs:98:5:98:18 | ExprStmt | match |
| main.rs:94:34:94:37 | Some | main.rs:94:39:94:42 | "x5" | |
| main.rs:94:34:94:43 | Some(...) | main.rs:94:9:94:16 | Some(...) | |
@@ -265,6 +267,7 @@ edges
| main.rs:104:11:105:12 | let ... = s1 | main.rs:105:11:105:12 | s1 | |
| main.rs:104:15:104:26 | Some(...) | main.rs:104:5:107:5 | while ... { ... } | no-match |
| main.rs:104:15:104:26 | Some(...) | main.rs:104:24:104:25 | s2 | match |
| main.rs:104:20:104:25 | ref s2 | main.rs:104:5:107:5 | while ... { ... } | no-match |
| main.rs:104:20:104:25 | ref s2 | main.rs:106:9:106:22 | ExprStmt | match |
| main.rs:104:24:104:25 | s2 | main.rs:104:20:104:25 | ref s2 | |
| main.rs:105:11:105:12 | s1 | main.rs:104:15:104:26 | Some(...) | |
@@ -301,6 +304,7 @@ edges
| main.rs:116:9:116:16 | Some(...) | main.rs:121:9:121:12 | None | no-match |
| main.rs:116:14:116:15 | y1 | main.rs:116:14:116:15 | y1 | |
| main.rs:116:14:116:15 | y1 | main.rs:119:13:119:21 | print_i64 | match |
| main.rs:116:14:116:15 | y1 | main.rs:121:9:121:12 | None | no-match |
| main.rs:118:9:120:9 | { ... } | main.rs:114:5:122:5 | match x6 { ... } | |
| main.rs:119:13:119:21 | print_i64 | main.rs:119:23:119:24 | y1 | |
| main.rs:119:13:119:25 | print_i64(...) | main.rs:118:9:120:9 | { ... } | |
@@ -400,12 +404,10 @@ edges
| main.rs:172:9:174:9 | ...::Hello {...} | main.rs:175:9:175:38 | ...::Hello {...} | no-match |
| main.rs:173:17:173:27 | id_variable | main.rs:173:17:173:35 | id_variable @ ... | |
| main.rs:173:17:173:35 | id_variable @ ... | main.rs:174:14:174:22 | print_i64 | match |
| main.rs:173:17:173:35 | id_variable @ ... | main.rs:175:9:175:38 | ...::Hello {...} | no-match |
| main.rs:173:31:173:31 | 3 | main.rs:173:31:173:31 | 3 | |
| main.rs:173:31:173:31 | 3 | main.rs:173:35:173:35 | 7 | match |
| main.rs:173:31:173:31 | 3 | main.rs:175:9:175:38 | ...::Hello {...} | no-match |
| main.rs:173:31:173:35 | RangePat | main.rs:173:31:173:31 | 3 | match |
| main.rs:173:31:173:35 | RangePat | main.rs:175:9:175:38 | ...::Hello {...} | no-match |
| main.rs:173:35:173:35 | 7 | main.rs:173:17:173:27 | id_variable | match |
| main.rs:173:35:173:35 | 7 | main.rs:173:35:173:35 | 7 | |
| main.rs:173:35:173:35 | 7 | main.rs:175:9:175:38 | ...::Hello {...} | no-match |
@@ -418,7 +420,6 @@ edges
| main.rs:175:30:175:31 | 10 | main.rs:175:35:175:36 | 12 | match |
| main.rs:175:30:175:31 | 10 | main.rs:178:9:178:29 | ...::Hello {...} | no-match |
| main.rs:175:30:175:36 | RangePat | main.rs:175:30:175:31 | 10 | match |
| main.rs:175:30:175:36 | RangePat | main.rs:178:9:178:29 | ...::Hello {...} | no-match |
| main.rs:175:35:175:36 | 12 | main.rs:175:35:175:36 | 12 | |
| main.rs:175:35:175:36 | 12 | main.rs:176:22:176:51 | MacroStmts | match |
| main.rs:175:35:175:36 | 12 | main.rs:178:9:178:29 | ...::Hello {...} | no-match |
@@ -456,6 +457,7 @@ edges
| main.rs:191:9:191:44 | ... \| ... | main.rs:192:16:192:24 | print_i64 | match |
| main.rs:191:22:191:23 | a3 | main.rs:191:9:191:44 | ... \| ... | match |
| main.rs:191:22:191:23 | a3 | main.rs:191:22:191:23 | a3 | |
| main.rs:191:22:191:23 | a3 | main.rs:191:28:191:44 | ...::Right(...) | no-match |
| main.rs:191:28:191:44 | ...::Right(...) | main.rs:191:42:191:43 | a3 | match |
| main.rs:191:42:191:43 | a3 | main.rs:191:9:191:44 | ... \| ... | match |
| main.rs:191:42:191:43 | a3 | main.rs:191:42:191:43 | a3 | |
@@ -479,10 +481,12 @@ edges
| main.rs:205:9:205:81 | ... \| ... \| ... | main.rs:206:16:206:24 | print_i64 | match |
| main.rs:205:28:205:29 | a4 | main.rs:205:9:205:81 | ... \| ... \| ... | match |
| main.rs:205:28:205:29 | a4 | main.rs:205:28:205:29 | a4 | |
| main.rs:205:28:205:29 | a4 | main.rs:205:34:205:56 | ...::Second(...) | no-match |
| main.rs:205:34:205:56 | ...::Second(...) | main.rs:205:54:205:55 | a4 | match |
| main.rs:205:34:205:56 | ...::Second(...) | main.rs:205:60:205:81 | ...::Third(...) | no-match |
| main.rs:205:54:205:55 | a4 | main.rs:205:9:205:81 | ... \| ... \| ... | match |
| main.rs:205:54:205:55 | a4 | main.rs:205:54:205:55 | a4 | |
| main.rs:205:54:205:55 | a4 | main.rs:205:60:205:81 | ...::Third(...) | no-match |
| main.rs:205:60:205:81 | ...::Third(...) | main.rs:205:79:205:80 | a4 | match |
| main.rs:205:79:205:80 | a4 | main.rs:205:9:205:81 | ... \| ... \| ... | match |
| main.rs:205:79:205:80 | a4 | main.rs:205:79:205:80 | a4 | |
@@ -499,8 +503,10 @@ edges
| main.rs:209:10:209:57 | [match(true)] ... \| ... | main.rs:209:9:209:83 | ... \| ... | match |
| main.rs:209:29:209:30 | a5 | main.rs:209:10:209:57 | [match(true)] ... \| ... | match |
| main.rs:209:29:209:30 | a5 | main.rs:209:29:209:30 | a5 | |
| main.rs:209:29:209:30 | a5 | main.rs:209:35:209:57 | ...::Second(...) | no-match |
| main.rs:209:35:209:57 | ...::Second(...) | main.rs:209:10:209:57 | [match(false)] ... \| ... | no-match |
| main.rs:209:35:209:57 | ...::Second(...) | main.rs:209:55:209:56 | a5 | match |
| main.rs:209:55:209:56 | a5 | main.rs:209:10:209:57 | [match(false)] ... \| ... | no-match |
| main.rs:209:55:209:56 | a5 | main.rs:209:10:209:57 | [match(true)] ... \| ... | match |
| main.rs:209:55:209:56 | a5 | main.rs:209:55:209:56 | a5 | |
| main.rs:209:62:209:83 | ...::Third(...) | main.rs:209:81:209:82 | a5 | match |
@@ -516,11 +522,13 @@ edges
| main.rs:213:9:213:83 | ... \| ... | main.rs:214:16:214:24 | print_i64 | match |
| main.rs:213:28:213:29 | a6 | main.rs:213:9:213:83 | ... \| ... | match |
| main.rs:213:28:213:29 | a6 | main.rs:213:28:213:29 | a6 | |
| main.rs:213:28:213:29 | a6 | main.rs:213:35:213:57 | ...::Second(...) | no-match |
| main.rs:213:35:213:57 | ...::Second(...) | main.rs:213:55:213:56 | a6 | match |
| main.rs:213:35:213:57 | ...::Second(...) | main.rs:213:61:213:82 | ...::Third(...) | no-match |
| main.rs:213:35:213:82 | ... \| ... | main.rs:213:9:213:83 | ... \| ... | match |
| main.rs:213:55:213:56 | a6 | main.rs:213:35:213:82 | ... \| ... | match |
| main.rs:213:55:213:56 | a6 | main.rs:213:55:213:56 | a6 | |
| main.rs:213:55:213:56 | a6 | main.rs:213:61:213:82 | ...::Third(...) | no-match |
| main.rs:213:61:213:82 | ...::Third(...) | main.rs:213:80:213:81 | a6 | match |
| main.rs:213:80:213:81 | a6 | main.rs:213:35:213:82 | ... \| ... | match |
| main.rs:213:80:213:81 | a6 | main.rs:213:80:213:81 | a6 | |
@@ -544,8 +552,10 @@ edges
| main.rs:221:9:221:44 | [match(true)] ... \| ... | main.rs:222:16:222:17 | a7 | match |
| main.rs:221:22:221:23 | a7 | main.rs:221:9:221:44 | [match(true)] ... \| ... | match |
| main.rs:221:22:221:23 | a7 | main.rs:221:22:221:23 | a7 | |
| main.rs:221:22:221:23 | a7 | main.rs:221:28:221:44 | ...::Right(...) | no-match |
| main.rs:221:28:221:44 | ...::Right(...) | main.rs:221:9:221:44 | [match(false)] ... \| ... | no-match |
| main.rs:221:28:221:44 | ...::Right(...) | main.rs:221:42:221:43 | a7 | match |
| main.rs:221:42:221:43 | a7 | main.rs:221:9:221:44 | [match(false)] ... \| ... | no-match |
| main.rs:221:42:221:43 | a7 | main.rs:221:9:221:44 | [match(true)] ... \| ... | match |
| main.rs:221:42:221:43 | a7 | main.rs:221:42:221:43 | a7 | |
| main.rs:222:16:222:17 | a7 | main.rs:222:21:222:21 | 0 | |
@@ -569,7 +579,6 @@ edges
| main.rs:231:5:242:5 | match either { ... } | main.rs:228:21:243:1 | { ... } | |
| main.rs:231:11:231:16 | either | main.rs:233:14:233:30 | ...::Left(...) | |
| main.rs:232:9:233:52 | ref e @ ... | main.rs:235:13:235:27 | ExprStmt | match |
| main.rs:232:9:233:52 | ref e @ ... | main.rs:241:9:241:9 | _ | no-match |
| main.rs:232:13:232:13 | e | main.rs:232:9:233:52 | ref e @ ... | |
| main.rs:233:14:233:30 | ...::Left(...) | main.rs:233:27:233:29 | a11 | match |
| main.rs:233:14:233:30 | ...::Left(...) | main.rs:233:34:233:51 | ...::Right(...) | no-match |
@@ -577,8 +586,10 @@ edges
| main.rs:233:14:233:51 | [match(true)] ... \| ... | main.rs:232:13:232:13 | e | match |
| main.rs:233:27:233:29 | a11 | main.rs:233:14:233:51 | [match(true)] ... \| ... | match |
| main.rs:233:27:233:29 | a11 | main.rs:233:27:233:29 | a11 | |
| main.rs:233:27:233:29 | a11 | main.rs:233:34:233:51 | ...::Right(...) | no-match |
| main.rs:233:34:233:51 | ...::Right(...) | main.rs:233:14:233:51 | [match(false)] ... \| ... | no-match |
| main.rs:233:34:233:51 | ...::Right(...) | main.rs:233:48:233:50 | a11 | match |
| main.rs:233:48:233:50 | a11 | main.rs:233:14:233:51 | [match(false)] ... \| ... | no-match |
| main.rs:233:48:233:50 | a11 | main.rs:233:14:233:51 | [match(true)] ... \| ... | match |
| main.rs:233:48:233:50 | a11 | main.rs:233:48:233:50 | a11 | |
| main.rs:234:12:240:9 | { ... } | main.rs:231:5:242:5 | match either { ... } | |
@@ -590,6 +601,7 @@ edges
| main.rs:236:16:237:15 | let ... = e | main.rs:237:15:237:15 | e | |
| main.rs:236:20:236:36 | ...::Left(...) | main.rs:236:13:239:13 | if ... {...} | no-match |
| main.rs:236:20:236:36 | ...::Left(...) | main.rs:236:33:236:35 | a12 | match |
| main.rs:236:33:236:35 | a12 | main.rs:236:13:239:13 | if ... {...} | no-match |
| main.rs:236:33:236:35 | a12 | main.rs:236:33:236:35 | a12 | |
| main.rs:236:33:236:35 | a12 | main.rs:238:17:238:32 | ExprStmt | match |
| main.rs:237:15:237:15 | e | main.rs:236:20:236:36 | ...::Left(...) | |
@@ -617,14 +629,17 @@ edges
| main.rs:255:9:255:109 | ... \| ... \| ... | main.rs:256:16:256:24 | print_i64 | match |
| main.rs:255:27:255:29 | a13 | main.rs:255:9:255:109 | ... \| ... \| ... | match |
| main.rs:255:27:255:29 | a13 | main.rs:255:27:255:29 | a13 | |
| main.rs:255:27:255:29 | a13 | main.rs:255:35:255:57 | ...::Second(...) | no-match |
| main.rs:255:35:255:57 | ...::Second(...) | main.rs:255:54:255:56 | a13 | match |
| main.rs:255:35:255:57 | ...::Second(...) | main.rs:255:61:255:82 | ...::Third(...) | no-match |
| main.rs:255:35:255:82 | [match(false)] ... \| ... | main.rs:255:87:255:109 | ...::Fourth(...) | no-match |
| main.rs:255:35:255:82 | [match(true)] ... \| ... | main.rs:255:9:255:109 | ... \| ... \| ... | match |
| main.rs:255:54:255:56 | a13 | main.rs:255:35:255:82 | [match(true)] ... \| ... | match |
| main.rs:255:54:255:56 | a13 | main.rs:255:54:255:56 | a13 | |
| main.rs:255:54:255:56 | a13 | main.rs:255:61:255:82 | ...::Third(...) | no-match |
| main.rs:255:61:255:82 | ...::Third(...) | main.rs:255:35:255:82 | [match(false)] ... \| ... | no-match |
| main.rs:255:61:255:82 | ...::Third(...) | main.rs:255:79:255:81 | a13 | match |
| main.rs:255:79:255:81 | a13 | main.rs:255:35:255:82 | [match(false)] ... \| ... | no-match |
| main.rs:255:79:255:81 | a13 | main.rs:255:35:255:82 | [match(true)] ... \| ... | match |
| main.rs:255:79:255:81 | a13 | main.rs:255:79:255:81 | a13 | |
| main.rs:255:87:255:109 | ...::Fourth(...) | main.rs:255:106:255:108 | a13 | match |
@@ -665,6 +680,7 @@ edges
| main.rs:272:6:272:41 | ... \| ... | main.rs:272:5:272:50 | ...: Either | match |
| main.rs:272:19:272:20 | a9 | main.rs:272:6:272:41 | ... \| ... | match |
| main.rs:272:19:272:20 | a9 | main.rs:272:19:272:20 | a9 | |
| main.rs:272:19:272:20 | a9 | main.rs:272:25:272:41 | ...::Right(...) | no-match |
| main.rs:272:25:272:41 | ...::Right(...) | main.rs:272:39:272:40 | a9 | match |
| main.rs:272:39:272:40 | a9 | main.rs:272:6:272:41 | ... \| ... | match |
| main.rs:272:39:272:40 | a9 | main.rs:272:39:272:40 | a9 | |