mirror of
https://github.com/github/codeql.git
synced 2026-04-26 01:05:15 +02:00
Rust: Add type inference tests for closures
This commit is contained in:
76
rust/ql/test/library-tests/type-inference/closure.rs
Normal file
76
rust/ql/test/library-tests/type-inference/closure.rs
Normal file
@@ -0,0 +1,76 @@
|
||||
/// Tests for type inference for closures and higher-order functions.
|
||||
|
||||
mod simple_closures {
|
||||
pub fn test() {
|
||||
// A simple closure without type annotations or invocations.
|
||||
let my_closure = |a, b| a && b;
|
||||
|
||||
let x: i64 = 1i64; // $ type=x:i64
|
||||
let add_one = |n| n + 1i64; // $ MISSING: target=add
|
||||
let _y = add_one(x); // $ MISSING: type=y:i64
|
||||
|
||||
// The type of `x` is inferred from the closure's argument type.
|
||||
let x = Default::default(); // $ MISSING: type=x:i64 target=default
|
||||
let add_zero = |n: i64| n;
|
||||
let _y = add_zero(x); // $ MISSING: type=_y:i64
|
||||
|
||||
let _get_bool = || -> bool {
|
||||
// The return type annotation on the closure lets us infer the type of `b`.
|
||||
let b = Default::default(); // $ MISSING: type=b:bool target=default
|
||||
b
|
||||
};
|
||||
|
||||
// The parameter type of `id` is inferred from the argument.
|
||||
let id = |b| b; // $ MISSING: type=x:bool
|
||||
let _b = id(true); // $ MISSING: type=_b:bool
|
||||
|
||||
// The return type of `id2` is inferred from the type of the call expression.
|
||||
let id2 = |b| b;
|
||||
let arg = Default::default(); // $ MISSING: target=default type=arg:bool
|
||||
let _b2: bool = id2(arg); // $ MISSING: type=_b:bool
|
||||
}
|
||||
}
|
||||
|
||||
mod fn_once_trait {
|
||||
fn return_type<F: FnOnce(bool) -> i64>(f: F) {
|
||||
let _return = f(true); // $ MISSING: type=_return:i64
|
||||
}
|
||||
|
||||
fn argument_type<F: FnOnce(bool) -> i64>(f: F) {
|
||||
let arg = Default::default(); // $ MISSING: type=arg:bool target=default
|
||||
f(arg);
|
||||
}
|
||||
|
||||
fn apply<A, B, F: FnOnce(A) -> B>(f: F, a: A) -> B {
|
||||
f(a)
|
||||
}
|
||||
|
||||
fn apply_two(f: impl FnOnce(i64) -> i64) -> i64 {
|
||||
f(2)
|
||||
}
|
||||
|
||||
fn test() {
|
||||
let f = |x: bool| -> i64 {
|
||||
if x {
|
||||
1
|
||||
} else {
|
||||
0
|
||||
}
|
||||
};
|
||||
let _r = apply(f, true); // $ target=apply MISSING: type=_r:i64
|
||||
|
||||
let f = |x| x + 1; // $ MISSING: type=x:i64 target=add
|
||||
let _r2 = apply_two(f); // $ target=apply_two type=_r2:i64
|
||||
}
|
||||
}
|
||||
|
||||
mod dyn_fn_once {
|
||||
fn apply_boxed<A, B, F: FnOnce(A) -> B + ?Sized>(f: Box<F>, arg: A) -> B {
|
||||
f(arg)
|
||||
}
|
||||
|
||||
fn apply_boxed_dyn<A, B>(f: Box<dyn FnOnce(A) -> B>, arg: A) {
|
||||
let _r1 = apply_boxed(f, arg); // $ target=apply_boxed MISSING: type=_r1:B
|
||||
let _r2 = apply_boxed(Box::new(|_: i64| true), 3); // $ target=apply_boxed target=new MISSING: type=_r2:bool
|
||||
}
|
||||
}
|
||||
@@ -2459,46 +2459,7 @@ pub mod pattern_matching_experimental {
|
||||
}
|
||||
}
|
||||
|
||||
mod closures {
|
||||
struct Row {
|
||||
data: i64,
|
||||
}
|
||||
|
||||
impl Row {
|
||||
fn get(&self) -> i64 {
|
||||
self.data // $ fieldof=Row
|
||||
}
|
||||
}
|
||||
|
||||
struct Table {
|
||||
rows: Vec<Row>,
|
||||
}
|
||||
|
||||
impl Table {
|
||||
fn new() -> Self {
|
||||
Table { rows: Vec::new() } // $ target=new
|
||||
}
|
||||
|
||||
fn count_with(&self, property: impl Fn(Row) -> bool) -> i64 {
|
||||
0 // (not implemented)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn f() {
|
||||
Some(1).map(|x| {
|
||||
let x = x; // $ MISSING: type=x:i32
|
||||
println!("{x}");
|
||||
}); // $ target=map
|
||||
|
||||
let table = Table::new(); // $ target=new type=table:Table
|
||||
let result = table.count_with(|row| // $ type=result:i64
|
||||
{
|
||||
let v = row.get(); // $ MISSING: target=get type=v:i64
|
||||
v > 0 // $ MISSING: target=gt
|
||||
}); // $ target=count_with
|
||||
}
|
||||
}
|
||||
|
||||
mod closure;
|
||||
mod dereference;
|
||||
mod dyn_type;
|
||||
|
||||
@@ -2532,6 +2493,5 @@ fn main() {
|
||||
dereference::test(); // $ target=test
|
||||
pattern_matching::test_all_patterns(); // $ target=test_all_patterns
|
||||
pattern_matching_experimental::box_patterns(); // $ target=box_patterns
|
||||
closures::f(); // $ target=f
|
||||
dyn_type::test(); // $ target=test
|
||||
}
|
||||
|
||||
@@ -1,4 +1,69 @@
|
||||
inferType
|
||||
| closure.rs:6:27:6:27 | a | | {EXTERNAL LOCATION} | bool |
|
||||
| closure.rs:6:30:6:30 | b | | {EXTERNAL LOCATION} | bool |
|
||||
| closure.rs:6:33:6:33 | a | | {EXTERNAL LOCATION} | bool |
|
||||
| closure.rs:6:33:6:38 | ... && ... | | {EXTERNAL LOCATION} | bool |
|
||||
| closure.rs:6:38:6:38 | b | | {EXTERNAL LOCATION} | bool |
|
||||
| closure.rs:8:13:8:13 | x | | {EXTERNAL LOCATION} | i64 |
|
||||
| closure.rs:8:22:8:25 | 1i64 | | {EXTERNAL LOCATION} | i64 |
|
||||
| closure.rs:9:31:9:34 | 1i64 | | {EXTERNAL LOCATION} | i64 |
|
||||
| closure.rs:10:26:10:26 | x | | {EXTERNAL LOCATION} | i64 |
|
||||
| closure.rs:14:25:14:25 | n | | {EXTERNAL LOCATION} | i64 |
|
||||
| closure.rs:14:33:14:33 | n | | {EXTERNAL LOCATION} | i64 |
|
||||
| closure.rs:25:21:25:24 | true | | {EXTERNAL LOCATION} | bool |
|
||||
| closure.rs:30:13:30:15 | _b2 | | {EXTERNAL LOCATION} | bool |
|
||||
| closure.rs:30:25:30:32 | id2(...) | | {EXTERNAL LOCATION} | bool |
|
||||
| closure.rs:35:44:35:44 | f | | closure.rs:35:20:35:41 | F |
|
||||
| closure.rs:36:23:36:23 | f | | closure.rs:35:20:35:41 | F |
|
||||
| closure.rs:36:25:36:28 | true | | {EXTERNAL LOCATION} | bool |
|
||||
| closure.rs:39:46:39:46 | f | | closure.rs:39:22:39:43 | F |
|
||||
| closure.rs:41:9:41:9 | f | | closure.rs:39:22:39:43 | F |
|
||||
| closure.rs:44:39:44:39 | f | | closure.rs:44:20:44:36 | F |
|
||||
| closure.rs:44:45:44:45 | a | | closure.rs:44:14:44:14 | A |
|
||||
| closure.rs:44:56:46:5 | { ... } | | closure.rs:44:17:44:17 | B |
|
||||
| closure.rs:45:9:45:9 | f | | closure.rs:44:20:44:36 | F |
|
||||
| closure.rs:45:9:45:12 | f(...) | | closure.rs:44:17:44:17 | B |
|
||||
| closure.rs:45:11:45:11 | a | | closure.rs:44:14:44:14 | A |
|
||||
| closure.rs:48:18:48:18 | f | | closure.rs:48:21:48:43 | ImplTraitTypeRepr |
|
||||
| closure.rs:48:53:50:5 | { ... } | | {EXTERNAL LOCATION} | i64 |
|
||||
| closure.rs:49:9:49:9 | f | | closure.rs:48:21:48:43 | ImplTraitTypeRepr |
|
||||
| closure.rs:49:9:49:12 | f(...) | | {EXTERNAL LOCATION} | i64 |
|
||||
| closure.rs:49:11:49:11 | 2 | | {EXTERNAL LOCATION} | i32 |
|
||||
| closure.rs:53:18:53:18 | x | | {EXTERNAL LOCATION} | bool |
|
||||
| closure.rs:53:34:59:9 | { ... } | | {EXTERNAL LOCATION} | i32 |
|
||||
| closure.rs:54:13:58:13 | if x {...} else {...} | | {EXTERNAL LOCATION} | i32 |
|
||||
| closure.rs:54:16:54:16 | x | | {EXTERNAL LOCATION} | bool |
|
||||
| closure.rs:54:18:56:13 | { ... } | | {EXTERNAL LOCATION} | i32 |
|
||||
| closure.rs:55:17:55:17 | 1 | | {EXTERNAL LOCATION} | i32 |
|
||||
| closure.rs:56:20:58:13 | { ... } | | {EXTERNAL LOCATION} | i32 |
|
||||
| closure.rs:57:17:57:17 | 0 | | {EXTERNAL LOCATION} | i32 |
|
||||
| closure.rs:60:27:60:30 | true | | {EXTERNAL LOCATION} | bool |
|
||||
| closure.rs:62:25:62:25 | 1 | | {EXTERNAL LOCATION} | i32 |
|
||||
| closure.rs:63:13:63:15 | _r2 | | {EXTERNAL LOCATION} | i64 |
|
||||
| closure.rs:63:19:63:30 | apply_two(...) | | {EXTERNAL LOCATION} | i64 |
|
||||
| closure.rs:68:54:68:54 | f | | {EXTERNAL LOCATION} | Box |
|
||||
| closure.rs:68:54:68:54 | f | A | {EXTERNAL LOCATION} | Global |
|
||||
| closure.rs:68:54:68:54 | f | T | closure.rs:68:26:68:51 | F |
|
||||
| closure.rs:68:65:68:67 | arg | | closure.rs:68:20:68:20 | A |
|
||||
| closure.rs:68:78:70:5 | { ... } | | closure.rs:68:23:68:23 | B |
|
||||
| closure.rs:69:9:69:9 | f | | {EXTERNAL LOCATION} | Box |
|
||||
| closure.rs:69:9:69:9 | f | A | {EXTERNAL LOCATION} | Global |
|
||||
| closure.rs:69:9:69:9 | f | T | closure.rs:68:26:68:51 | F |
|
||||
| closure.rs:69:9:69:14 | f(...) | | closure.rs:68:23:68:23 | B |
|
||||
| closure.rs:69:11:69:13 | arg | | closure.rs:68:20:68:20 | A |
|
||||
| closure.rs:72:30:72:30 | f | | {EXTERNAL LOCATION} | Box |
|
||||
| closure.rs:72:30:72:30 | f | A | {EXTERNAL LOCATION} | Global |
|
||||
| closure.rs:72:30:72:30 | f | T | {EXTERNAL LOCATION} | dyn FnOnce |
|
||||
| closure.rs:72:58:72:60 | arg | | closure.rs:72:24:72:24 | A |
|
||||
| closure.rs:73:31:73:31 | f | | {EXTERNAL LOCATION} | Box |
|
||||
| closure.rs:73:31:73:31 | f | A | {EXTERNAL LOCATION} | Global |
|
||||
| closure.rs:73:31:73:31 | f | T | {EXTERNAL LOCATION} | dyn FnOnce |
|
||||
| closure.rs:73:34:73:36 | arg | | closure.rs:72:24:72:24 | A |
|
||||
| closure.rs:74:31:74:53 | ...::new(...) | | {EXTERNAL LOCATION} | Box |
|
||||
| closure.rs:74:31:74:53 | ...::new(...) | A | {EXTERNAL LOCATION} | Global |
|
||||
| closure.rs:74:41:74:41 | _ | | {EXTERNAL LOCATION} | i64 |
|
||||
| closure.rs:74:49:74:52 | true | | {EXTERNAL LOCATION} | bool |
|
||||
| closure.rs:74:56:74:56 | 3 | | {EXTERNAL LOCATION} | i32 |
|
||||
| dereference.rs:12:14:12:18 | SelfParam | | file://:0:0:0:0 | & |
|
||||
| dereference.rs:12:14:12:18 | SelfParam | &T | dereference.rs:4:1:6:1 | MyIntPointer |
|
||||
| dereference.rs:12:29:14:5 | { ... } | | file://:0:0:0:0 | & |
|
||||
@@ -4528,43 +4593,11 @@ inferType
|
||||
| main.rs:2456:26:2456:43 | "Nested boxed: {}\\n" | &T | {EXTERNAL LOCATION} | str |
|
||||
| main.rs:2456:26:2456:59 | FormatArgsExpr | | {EXTERNAL LOCATION} | Arguments |
|
||||
| main.rs:2456:26:2456:59 | MacroExpr | | {EXTERNAL LOCATION} | Arguments |
|
||||
| main.rs:2468:16:2468:20 | SelfParam | | file://:0:0:0:0 | & |
|
||||
| main.rs:2468:16:2468:20 | SelfParam | &T | main.rs:2463:5:2465:5 | Row |
|
||||
| main.rs:2468:30:2470:9 | { ... } | | {EXTERNAL LOCATION} | i64 |
|
||||
| main.rs:2469:13:2469:16 | self | | file://:0:0:0:0 | & |
|
||||
| main.rs:2469:13:2469:16 | self | &T | main.rs:2463:5:2465:5 | Row |
|
||||
| main.rs:2469:13:2469:21 | self.data | | {EXTERNAL LOCATION} | i64 |
|
||||
| main.rs:2478:26:2480:9 | { ... } | | main.rs:2473:5:2475:5 | Table |
|
||||
| main.rs:2479:13:2479:38 | Table {...} | | main.rs:2473:5:2475:5 | Table |
|
||||
| main.rs:2479:27:2479:36 | ...::new(...) | | {EXTERNAL LOCATION} | Vec |
|
||||
| main.rs:2479:27:2479:36 | ...::new(...) | A | {EXTERNAL LOCATION} | Global |
|
||||
| main.rs:2479:27:2479:36 | ...::new(...) | T | main.rs:2463:5:2465:5 | Row |
|
||||
| main.rs:2482:23:2482:27 | SelfParam | | file://:0:0:0:0 | & |
|
||||
| main.rs:2482:23:2482:27 | SelfParam | &T | main.rs:2473:5:2475:5 | Table |
|
||||
| main.rs:2482:30:2482:37 | property | | main.rs:2482:40:2482:59 | ImplTraitTypeRepr |
|
||||
| main.rs:2482:69:2484:9 | { ... } | | {EXTERNAL LOCATION} | i32 |
|
||||
| main.rs:2482:69:2484:9 | { ... } | | {EXTERNAL LOCATION} | i64 |
|
||||
| main.rs:2483:13:2483:13 | 0 | | {EXTERNAL LOCATION} | i32 |
|
||||
| main.rs:2483:13:2483:13 | 0 | | {EXTERNAL LOCATION} | i64 |
|
||||
| main.rs:2488:9:2488:15 | Some(...) | | {EXTERNAL LOCATION} | Option |
|
||||
| main.rs:2488:9:2488:15 | Some(...) | T | {EXTERNAL LOCATION} | i32 |
|
||||
| main.rs:2488:9:2491:10 | ... .map(...) | | {EXTERNAL LOCATION} | Option |
|
||||
| main.rs:2488:14:2488:14 | 1 | | {EXTERNAL LOCATION} | i32 |
|
||||
| main.rs:2490:22:2490:26 | "{x}\\n" | | file://:0:0:0:0 | & |
|
||||
| main.rs:2490:22:2490:26 | "{x}\\n" | &T | {EXTERNAL LOCATION} | str |
|
||||
| main.rs:2490:22:2490:26 | FormatArgsExpr | | {EXTERNAL LOCATION} | Arguments |
|
||||
| main.rs:2490:22:2490:26 | MacroExpr | | {EXTERNAL LOCATION} | Arguments |
|
||||
| main.rs:2493:13:2493:17 | table | | main.rs:2473:5:2475:5 | Table |
|
||||
| main.rs:2493:21:2493:32 | ...::new(...) | | main.rs:2473:5:2475:5 | Table |
|
||||
| main.rs:2494:13:2494:18 | result | | {EXTERNAL LOCATION} | i64 |
|
||||
| main.rs:2494:22:2494:26 | table | | main.rs:2473:5:2475:5 | Table |
|
||||
| main.rs:2494:22:2498:14 | table.count_with(...) | | {EXTERNAL LOCATION} | i64 |
|
||||
| main.rs:2497:21:2497:21 | 0 | | {EXTERNAL LOCATION} | i32 |
|
||||
| main.rs:2507:5:2507:20 | ...::f(...) | | main.rs:72:5:72:21 | Foo |
|
||||
| main.rs:2508:5:2508:60 | ...::g(...) | | main.rs:72:5:72:21 | Foo |
|
||||
| main.rs:2508:20:2508:38 | ...::Foo {...} | | main.rs:72:5:72:21 | Foo |
|
||||
| main.rs:2508:41:2508:59 | ...::Foo {...} | | main.rs:72:5:72:21 | Foo |
|
||||
| main.rs:2524:5:2524:15 | ...::f(...) | | {EXTERNAL LOCATION} | trait Future |
|
||||
| main.rs:2468:5:2468:20 | ...::f(...) | | main.rs:72:5:72:21 | Foo |
|
||||
| main.rs:2469:5:2469:60 | ...::g(...) | | main.rs:72:5:72:21 | Foo |
|
||||
| main.rs:2469:20:2469:38 | ...::Foo {...} | | main.rs:72:5:72:21 | Foo |
|
||||
| main.rs:2469:41:2469:59 | ...::Foo {...} | | main.rs:72:5:72:21 | Foo |
|
||||
| main.rs:2485:5:2485:15 | ...::f(...) | | {EXTERNAL LOCATION} | trait Future |
|
||||
| pattern_matching.rs:13:26:133:1 | { ... } | | {EXTERNAL LOCATION} | Option |
|
||||
| pattern_matching.rs:13:26:133:1 | { ... } | T | file://:0:0:0:0 | () |
|
||||
| pattern_matching.rs:14:9:14:13 | value | | {EXTERNAL LOCATION} | Option |
|
||||
|
||||
Reference in New Issue
Block a user