Skip to content

Commit f7021ab

Browse files
committed
Rust: Type inference for ? expressions
1 parent fa0153b commit f7021ab

File tree

3 files changed

+28
-3
lines changed

3 files changed

+28
-3
lines changed

rust/ql/lib/codeql/rust/internal/TypeInference.qll

+14
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ private import Type
66
private import Type as T
77
private import TypeMention
88
private import codeql.typeinference.internal.TypeInference
9+
private import codeql.rust.frameworks.stdlib.Stdlib
910

1011
class Type = T::Type;
1112

@@ -891,6 +892,17 @@ private Type inferRefExprType(Expr e, TypePath path) {
891892
)
892893
}
893894

895+
pragma[nomagic]
896+
private Type inferTryExprType(TryExpr te, TypePath path) {
897+
exists(TypeParam tp |
898+
result = inferType(te.getExpr(), TypePath::cons(TTypeParamTypeParameter(tp), path))
899+
|
900+
tp = any(ResultEnum r).getGenericParamList().getGenericParam(0)
901+
or
902+
tp = any(OptionEnum o).getGenericParamList().getGenericParam(0)
903+
)
904+
}
905+
894906
cached
895907
private module Cached {
896908
private import codeql.rust.internal.CachedStages
@@ -1008,6 +1020,8 @@ private module Cached {
10081020
result = inferFieldExprType(n, path)
10091021
or
10101022
result = inferRefExprType(n, path)
1023+
or
1024+
result = inferTryExprType(n, path)
10111025
}
10121026
}
10131027

rust/ql/test/library-tests/type-inference/main.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -957,22 +957,22 @@ mod try_expressions {
957957

958958
// Simple function using ? operator with same error types
959959
fn try_same_error() -> Result<S1, S1> {
960-
let x = Result::Ok(S1)?; // $ MISSING: type=x:S1
960+
let x = Result::Ok(S1)?; // $ type=x:S1
961961
Result::Ok(S1)
962962
}
963963

964964
// Function using ? operator with different error types that need conversion
965965
fn try_convert_error() -> Result<S1, S2> {
966966
let x = Result::Ok(S1);
967-
let y = x?; // $ MISSING: type=y:S1
967+
let y = x?; // $ type=y:S1
968968
Result::Ok(S1)
969969
}
970970

971971
// Chained ? operations
972972
fn try_chained() -> Result<S1, S2> {
973973
let x = Result::Ok(Result::Ok(S1));
974974
// First ? returns Result<S1, S2>, second ? returns S1
975-
let y = x?.map(|s| s)?; // $ MISSING: method=map
975+
let y = x?.map(|s| s)?; // $ method=map
976976
Result::Ok(S1)
977977
}
978978

rust/ql/test/library-tests/type-inference/type-inference.expected

+11
Original file line numberDiff line numberDiff line change
@@ -1018,8 +1018,10 @@ inferType
10181018
| main.rs:959:43:962:5 | { ... } | | file://:0:0:0:0 | Result |
10191019
| main.rs:959:43:962:5 | { ... } | E | main.rs:952:5:953:14 | S1 |
10201020
| main.rs:959:43:962:5 | { ... } | T | main.rs:952:5:953:14 | S1 |
1021+
| main.rs:960:13:960:13 | x | | main.rs:952:5:953:14 | S1 |
10211022
| main.rs:960:17:960:30 | ...::Ok(...) | | file://:0:0:0:0 | Result |
10221023
| main.rs:960:17:960:30 | ...::Ok(...) | T | main.rs:952:5:953:14 | S1 |
1024+
| main.rs:960:17:960:31 | TryExpr | | main.rs:952:5:953:14 | S1 |
10231025
| main.rs:960:28:960:29 | S1 | | main.rs:952:5:953:14 | S1 |
10241026
| main.rs:961:9:961:22 | ...::Ok(...) | | file://:0:0:0:0 | Result |
10251027
| main.rs:961:9:961:22 | ...::Ok(...) | E | main.rs:952:5:953:14 | S1 |
@@ -1033,8 +1035,10 @@ inferType
10331035
| main.rs:966:17:966:30 | ...::Ok(...) | | file://:0:0:0:0 | Result |
10341036
| main.rs:966:17:966:30 | ...::Ok(...) | T | main.rs:952:5:953:14 | S1 |
10351037
| main.rs:966:28:966:29 | S1 | | main.rs:952:5:953:14 | S1 |
1038+
| main.rs:967:13:967:13 | y | | main.rs:952:5:953:14 | S1 |
10361039
| main.rs:967:17:967:17 | x | | file://:0:0:0:0 | Result |
10371040
| main.rs:967:17:967:17 | x | T | main.rs:952:5:953:14 | S1 |
1041+
| main.rs:967:17:967:18 | TryExpr | | main.rs:952:5:953:14 | S1 |
10381042
| main.rs:968:9:968:22 | ...::Ok(...) | | file://:0:0:0:0 | Result |
10391043
| main.rs:968:9:968:22 | ...::Ok(...) | E | main.rs:955:5:956:14 | S2 |
10401044
| main.rs:968:9:968:22 | ...::Ok(...) | T | main.rs:952:5:953:14 | S1 |
@@ -1054,6 +1058,9 @@ inferType
10541058
| main.rs:975:17:975:17 | x | | file://:0:0:0:0 | Result |
10551059
| main.rs:975:17:975:17 | x | T | file://:0:0:0:0 | Result |
10561060
| main.rs:975:17:975:17 | x | T.T | main.rs:952:5:953:14 | S1 |
1061+
| main.rs:975:17:975:18 | TryExpr | | file://:0:0:0:0 | Result |
1062+
| main.rs:975:17:975:18 | TryExpr | T | main.rs:952:5:953:14 | S1 |
1063+
| main.rs:975:17:975:29 | ... .map(...) | | file://:0:0:0:0 | Result |
10571064
| main.rs:976:9:976:22 | ...::Ok(...) | | file://:0:0:0:0 | Result |
10581065
| main.rs:976:9:976:22 | ...::Ok(...) | E | main.rs:955:5:956:14 | S2 |
10591066
| main.rs:976:9:976:22 | ...::Ok(...) | T | main.rs:952:5:953:14 | S1 |
@@ -1064,11 +1071,15 @@ inferType
10641071
| main.rs:980:69:987:5 | { ... } | | file://:0:0:0:0 | Result |
10651072
| main.rs:980:69:987:5 | { ... } | E | main.rs:952:5:953:14 | S1 |
10661073
| main.rs:980:69:987:5 | { ... } | T | main.rs:980:20:980:27 | T |
1074+
| main.rs:981:13:981:17 | value | | main.rs:980:20:980:27 | T |
10671075
| main.rs:981:21:981:25 | input | | file://:0:0:0:0 | Result |
10681076
| main.rs:981:21:981:25 | input | E | main.rs:952:5:953:14 | S1 |
10691077
| main.rs:981:21:981:25 | input | T | main.rs:980:20:980:27 | T |
1078+
| main.rs:981:21:981:26 | TryExpr | | main.rs:980:20:980:27 | T |
10701079
| main.rs:982:22:982:38 | ...::Ok(...) | | file://:0:0:0:0 | Result |
1080+
| main.rs:982:22:982:38 | ...::Ok(...) | T | main.rs:980:20:980:27 | T |
10711081
| main.rs:982:22:985:10 | ... .and_then(...) | | file://:0:0:0:0 | Result |
1082+
| main.rs:982:33:982:37 | value | | main.rs:980:20:980:27 | T |
10721083
| main.rs:982:53:985:9 | { ... } | | file://:0:0:0:0 | Result |
10731084
| main.rs:982:53:985:9 | { ... } | E | main.rs:952:5:953:14 | S1 |
10741085
| main.rs:984:13:984:34 | ...::Ok::<...>(...) | | file://:0:0:0:0 | Result |

0 commit comments

Comments
 (0)