Skip to content

Commit 70f9700

Browse files
committed
Rust: Add tests for chained let expressions
1 parent 0a67902 commit 70f9700

File tree

11 files changed

+4608
-4469
lines changed

11 files changed

+4608
-4469
lines changed
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
multipleCallTargets
2-
| main.rs:445:18:445:24 | n.len() |
2+
| main.rs:471:18:471:24 | n.len() |

rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected

Lines changed: 1094 additions & 1079 deletions
Large diffs are not rendered by default.

rust/ql/test/library-tests/dataflow/local/inline-flow.expected

Lines changed: 545 additions & 545 deletions
Large diffs are not rendered by default.

rust/ql/test/library-tests/dataflow/local/main.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#![feature(let_chains)]
12
// Tests for intraprocedural data flow.
23

34
fn source(i: i64) -> i64 {
@@ -21,6 +22,19 @@ fn direct() {
2122
fn variable_usage() {
2223
let s = source(2);
2324
sink(s); // $ hasValueFlow=2
25+
26+
if let x = s {
27+
sink(x); // $ MISSING: hasValueFlow=2
28+
};
29+
30+
if let x = s
31+
&& {
32+
sink(x); // $ MISSING: hasValueFlow=2
33+
true
34+
}
35+
{
36+
sink(x); // $ MISSING: hasValueFlow=2
37+
};
2438
}
2539

2640
fn if_expression(cond: bool) {
@@ -236,6 +250,18 @@ fn option_pattern_match_unqualified() {
236250
}
237251
}
238252

253+
fn option_chained_let() {
254+
let s1 = Some(source(45));
255+
if let Some(n) = s1
256+
&& {
257+
sink(n); // $ MISSING: hasValueFlow=45
258+
true
259+
}
260+
{
261+
sink(n); // $ MISSING: hasValueFlow=45
262+
}
263+
}
264+
239265
fn option_unwrap() {
240266
let s1 = Some(source(19));
241267
sink(s1.unwrap()); // $ hasValueFlow=19
@@ -558,6 +584,7 @@ fn main() {
558584
struct_nested_match();
559585
option_pattern_match_qualified();
560586
option_pattern_match_unqualified();
587+
option_chained_let();
561588
option_unwrap();
562589
option_unwrap_or();
563590
option_questionmark();
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
qltest_use_nightly: true
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
multipleCallTargets
2-
| main.rs:87:19:87:40 | ...::from(...) |
3-
| main.rs:106:19:106:40 | ...::from(...) |
2+
| main.rs:88:19:88:40 | ...::from(...) |
3+
| main.rs:107:19:107:40 | ...::from(...) |

rust/ql/test/library-tests/variables/Cfg.expected

Lines changed: 1658 additions & 1630 deletions
Large diffs are not rendered by default.

rust/ql/test/library-tests/variables/Ssa.expected

Lines changed: 666 additions & 658 deletions
Large diffs are not rendered by default.

rust/ql/test/library-tests/variables/main.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#![feature(let_chains)]
12
use std::ops::AddAssign;
23

34
fn print_str(s: &str) // s
@@ -269,6 +270,37 @@ fn match_pattern9() {
269270
}
270271
}
271272

273+
#[rustfmt::skip]
274+
fn match_pattern10() {
275+
let o = Some(42); // o
276+
if let Some(x)
277+
= o // $ read_access=o
278+
&&
279+
x > 0 // $ MISSING: read_access=x
280+
{
281+
print_i64(x); // $ MISSING: read_access=x
282+
} else {
283+
print_str("No value");
284+
}
285+
}
286+
287+
#[rustfmt::skip]
288+
fn match_pattern11() {
289+
let x = Some(42); // x1
290+
if let Some(x) // x2
291+
= x // $ read_access=x1
292+
&&
293+
let Some(x) // x3
294+
= Some(x) // $ MISSING: read_access=x2 $ SPURIOUS: read_access=x1
295+
&&
296+
x > 0 // $ MISSING: read_access=x3 $ SPURIOUS: read_access=x1
297+
{
298+
print_i64(x); // $ MISSING: read_access=x3 $ SPURIOUS: read_access=x1
299+
} else {
300+
print_str("No value");
301+
}
302+
}
303+
272304
fn param_pattern1(
273305
a8: &str, // a8
274306
(
@@ -417,6 +449,7 @@ fn mutate_arg() {
417449
let y = // y
418450
mutate_param(&mut x); // $ access=x
419451
*y = 10; // $ read_access=y
452+
420453
// prints 10, not 4
421454
print_i64(x); // $ read_access=x
422455

@@ -428,6 +461,7 @@ fn mutate_arg() {
428461
w, // $ read_access=w
429462
);
430463
**w = 11; // $ read_access=w
464+
431465
// prints 11, not 8
432466
print_i64(z); // $ read_access=z
433467
}
@@ -442,6 +476,7 @@ fn alias() {
442476

443477
fn capture_immut() {
444478
let x = 100; // x
479+
445480
// Captures immutable value by immutable reference
446481
let cap = || {
447482
print_i64(x); // $ read_access=x
@@ -452,6 +487,7 @@ fn capture_immut() {
452487

453488
fn capture_mut() {
454489
let mut x = 1; // x
490+
455491
// Captures mutable value by immutable reference
456492
let closure1 = || {
457493
print_i64(x); // $ read_access=x
@@ -460,6 +496,7 @@ fn capture_mut() {
460496
print_i64(x); // $ read_access=x
461497

462498
let mut y = 2; // y
499+
463500
// Captures mutable value by mutable reference
464501
let mut closure2 = || {
465502
y = 3; // $ write_access=y
@@ -468,6 +505,7 @@ fn capture_mut() {
468505
print_i64(y); // $ read_access=y
469506

470507
let mut z = 2; // z
508+
471509
// Captures mutable value by mutable reference and calls mutating method
472510
let mut closure3 = || {
473511
z.add_assign(1); // $ read_access=z
@@ -586,6 +624,7 @@ impl MyStruct {
586624
fn ref_methodcall_receiver() {
587625
let mut a = MyStruct { val: 1 }; // a
588626
a.bar(); // $ read_access=a
627+
589628
// prints 3, not 1
590629
print_i64(a.val); // $ read_access=a
591630
}
@@ -609,6 +648,7 @@ fn macro_invocation() {
609648
let_in_macro!(37); // $ read_access=var_in_macro
610649
print_i64(var_from_macro); // $ read_access=var_from_macro1
611650
let var_in_macro = 33; // var_in_macro1
651+
612652
// Our analysis does not currently respect the hygiene rules of Rust macros
613653
// (https://veykril.github.io/tlborm/decl-macros/minutiae/hygiene.html), because
614654
// all we have access to is the expanded AST
@@ -653,6 +693,8 @@ fn main() {
653693
match_pattern7();
654694
match_pattern8();
655695
match_pattern9();
696+
match_pattern10();
697+
match_pattern11();
656698
param_pattern1("a", ("b", "c"));
657699
param_pattern2(Either::Left(45));
658700
destruct_assignment();
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
qltest_use_nightly: true

0 commit comments

Comments
 (0)