Skip to content

Commit 01701de

Browse files
committed
Rust: Implement type inference for ref expression as type equality
1 parent 8f5d9d7 commit 01701de

File tree

3 files changed

+62
-47
lines changed

3 files changed

+62
-47
lines changed

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

Lines changed: 8 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,10 @@ private predicate typeEquality(AstNode n1, TypePath prefix1, AstNode n2, TypePat
257257
)
258258
)
259259
or
260+
n1 = n2.(RefExpr).getExpr() and
261+
prefix1.isEmpty() and
262+
prefix2 = TypePath::singleton(TRefTypeParameter())
263+
or
260264
n1 = n2.(DerefExpr).getExpr() and
261265
prefix1 = TypePath::singleton(TRefTypeParameter()) and
262266
prefix2.isEmpty()
@@ -973,43 +977,9 @@ private Type inferFieldExprType(AstNode n, TypePath path) {
973977
)
974978
}
975979

976-
/**
977-
* Gets the type of `n` at `path`, where `n` is either a reference expression
978-
* `& x` or an expression `x` inside a reference expression `& x`.
979-
*/
980+
/** Gets the root type of the reference expression `re`. */
980981
pragma[nomagic]
981-
private Type inferRefExprType(Expr e, TypePath path) {
982-
exists(RefExpr re |
983-
e = re and
984-
path.isEmpty() and
985-
result = TRefType()
986-
or
987-
e = re and
988-
exists(TypePath exprPath | result = inferType(re.getExpr(), exprPath) |
989-
if exprPath.isCons(TRefTypeParameter(), _)
990-
then
991-
// `&x` simply means `x` when `x` already has reference type
992-
path = exprPath
993-
else (
994-
path = TypePath::cons(TRefTypeParameter(), exprPath) and
995-
not (exprPath.isEmpty() and result = TRefType())
996-
)
997-
)
998-
or
999-
e = re.getExpr() and
1000-
exists(TypePath exprPath, TypePath refPath, Type exprType |
1001-
result = inferType(re, exprPath) and
1002-
exprPath.isCons(TRefTypeParameter(), refPath) and
1003-
exprType = inferType(e)
1004-
|
1005-
if exprType = TRefType()
1006-
then
1007-
// `&x` simply means `x` when `x` already has reference type
1008-
path = exprPath
1009-
else path = refPath
1010-
)
1011-
)
1012-
}
982+
private Type inferRefExprType(RefExpr re) { exists(re) and result = TRefType() }
1013983

1014984
pragma[nomagic]
1015985
private Type inferTryExprType(TryExpr te, TypePath path) {
@@ -1505,7 +1475,8 @@ private module Cached {
15051475
or
15061476
result = inferFieldExprType(n, path)
15071477
or
1508-
result = inferRefExprType(n, path)
1478+
result = inferRefExprType(n) and
1479+
path.isEmpty()
15091480
or
15101481
result = inferTryExprType(n, path)
15111482
or

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1191,13 +1191,13 @@ mod borrowed_typed {
11911191
x.f2(); // $ method=f2
11921192
S::f3(&x);
11931193

1194-
let n = **&&true; // $ MISSING: type=n:bool
1194+
let n = **&&true; // $ type=n:bool
11951195

11961196
// In this example the type of `flag` must be inferred at the call to
11971197
// `flip` and flow through the borrow in the argument.
11981198
let mut flag = Default::default();
11991199
MyFlag::flip(&mut flag);
1200-
println!("{:?}", flag); // $ MISSING: type=flag:MyFlag
1200+
println!("{:?}", flag); // $ type=flag:MyFlag
12011201
}
12021202
}
12031203

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

Lines changed: 52 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1442,25 +1442,49 @@ inferType
14421442
| main.rs:1171:15:1171:19 | SelfParam | | file://:0:0:0:0 | & |
14431443
| main.rs:1171:15:1171:19 | SelfParam | &T | main.rs:1168:5:1168:13 | S |
14441444
| main.rs:1171:31:1173:9 | { ... } | | file://:0:0:0:0 | & |
1445+
| main.rs:1171:31:1173:9 | { ... } | &T | file://:0:0:0:0 | & |
14451446
| main.rs:1171:31:1173:9 | { ... } | &T | main.rs:1168:5:1168:13 | S |
1447+
| main.rs:1171:31:1173:9 | { ... } | &T.&T | file://:0:0:0:0 | & |
1448+
| main.rs:1171:31:1173:9 | { ... } | &T.&T.&T | file://:0:0:0:0 | & |
1449+
| main.rs:1171:31:1173:9 | { ... } | &T.&T.&T.&T | main.rs:1168:5:1168:13 | S |
14461450
| main.rs:1172:13:1172:19 | &... | | file://:0:0:0:0 | & |
1451+
| main.rs:1172:13:1172:19 | &... | &T | file://:0:0:0:0 | & |
14471452
| main.rs:1172:13:1172:19 | &... | &T | main.rs:1168:5:1168:13 | S |
1453+
| main.rs:1172:13:1172:19 | &... | &T.&T | file://:0:0:0:0 | & |
1454+
| main.rs:1172:13:1172:19 | &... | &T.&T.&T | file://:0:0:0:0 | & |
1455+
| main.rs:1172:13:1172:19 | &... | &T.&T.&T.&T | main.rs:1168:5:1168:13 | S |
14481456
| main.rs:1172:14:1172:19 | &... | | file://:0:0:0:0 | & |
1449-
| main.rs:1172:14:1172:19 | &... | &T | main.rs:1168:5:1168:13 | S |
1457+
| main.rs:1172:14:1172:19 | &... | | main.rs:1168:5:1168:13 | S |
1458+
| main.rs:1172:14:1172:19 | &... | &T | file://:0:0:0:0 | & |
1459+
| main.rs:1172:14:1172:19 | &... | &T.&T | file://:0:0:0:0 | & |
1460+
| main.rs:1172:14:1172:19 | &... | &T.&T.&T | main.rs:1168:5:1168:13 | S |
14501461
| main.rs:1172:15:1172:19 | &self | | file://:0:0:0:0 | & |
1451-
| main.rs:1172:15:1172:19 | &self | &T | main.rs:1168:5:1168:13 | S |
1462+
| main.rs:1172:15:1172:19 | &self | &T | file://:0:0:0:0 | & |
1463+
| main.rs:1172:15:1172:19 | &self | &T.&T | main.rs:1168:5:1168:13 | S |
14521464
| main.rs:1172:16:1172:19 | self | | file://:0:0:0:0 | & |
14531465
| main.rs:1172:16:1172:19 | self | &T | main.rs:1168:5:1168:13 | S |
14541466
| main.rs:1175:15:1175:25 | SelfParam | | file://:0:0:0:0 | & |
14551467
| main.rs:1175:15:1175:25 | SelfParam | &T | main.rs:1168:5:1168:13 | S |
14561468
| main.rs:1175:37:1177:9 | { ... } | | file://:0:0:0:0 | & |
1469+
| main.rs:1175:37:1177:9 | { ... } | &T | file://:0:0:0:0 | & |
14571470
| main.rs:1175:37:1177:9 | { ... } | &T | main.rs:1168:5:1168:13 | S |
1471+
| main.rs:1175:37:1177:9 | { ... } | &T.&T | file://:0:0:0:0 | & |
1472+
| main.rs:1175:37:1177:9 | { ... } | &T.&T.&T | file://:0:0:0:0 | & |
1473+
| main.rs:1175:37:1177:9 | { ... } | &T.&T.&T.&T | main.rs:1168:5:1168:13 | S |
14581474
| main.rs:1176:13:1176:19 | &... | | file://:0:0:0:0 | & |
1475+
| main.rs:1176:13:1176:19 | &... | &T | file://:0:0:0:0 | & |
14591476
| main.rs:1176:13:1176:19 | &... | &T | main.rs:1168:5:1168:13 | S |
1477+
| main.rs:1176:13:1176:19 | &... | &T.&T | file://:0:0:0:0 | & |
1478+
| main.rs:1176:13:1176:19 | &... | &T.&T.&T | file://:0:0:0:0 | & |
1479+
| main.rs:1176:13:1176:19 | &... | &T.&T.&T.&T | main.rs:1168:5:1168:13 | S |
14601480
| main.rs:1176:14:1176:19 | &... | | file://:0:0:0:0 | & |
1461-
| main.rs:1176:14:1176:19 | &... | &T | main.rs:1168:5:1168:13 | S |
1481+
| main.rs:1176:14:1176:19 | &... | | main.rs:1168:5:1168:13 | S |
1482+
| main.rs:1176:14:1176:19 | &... | &T | file://:0:0:0:0 | & |
1483+
| main.rs:1176:14:1176:19 | &... | &T.&T | file://:0:0:0:0 | & |
1484+
| main.rs:1176:14:1176:19 | &... | &T.&T.&T | main.rs:1168:5:1168:13 | S |
14621485
| main.rs:1176:15:1176:19 | &self | | file://:0:0:0:0 | & |
1463-
| main.rs:1176:15:1176:19 | &self | &T | main.rs:1168:5:1168:13 | S |
1486+
| main.rs:1176:15:1176:19 | &self | &T | file://:0:0:0:0 | & |
1487+
| main.rs:1176:15:1176:19 | &self | &T.&T | main.rs:1168:5:1168:13 | S |
14641488
| main.rs:1176:16:1176:19 | self | | file://:0:0:0:0 | & |
14651489
| main.rs:1176:16:1176:19 | self | &T | main.rs:1168:5:1168:13 | S |
14661490
| main.rs:1179:15:1179:15 | x | | file://:0:0:0:0 | & |
@@ -1472,13 +1496,25 @@ inferType
14721496
| main.rs:1183:15:1183:15 | x | | file://:0:0:0:0 | & |
14731497
| main.rs:1183:15:1183:15 | x | &T | main.rs:1168:5:1168:13 | S |
14741498
| main.rs:1183:34:1185:9 | { ... } | | file://:0:0:0:0 | & |
1499+
| main.rs:1183:34:1185:9 | { ... } | &T | file://:0:0:0:0 | & |
14751500
| main.rs:1183:34:1185:9 | { ... } | &T | main.rs:1168:5:1168:13 | S |
1501+
| main.rs:1183:34:1185:9 | { ... } | &T.&T | file://:0:0:0:0 | & |
1502+
| main.rs:1183:34:1185:9 | { ... } | &T.&T.&T | file://:0:0:0:0 | & |
1503+
| main.rs:1183:34:1185:9 | { ... } | &T.&T.&T.&T | main.rs:1168:5:1168:13 | S |
14761504
| main.rs:1184:13:1184:16 | &... | | file://:0:0:0:0 | & |
1505+
| main.rs:1184:13:1184:16 | &... | &T | file://:0:0:0:0 | & |
14771506
| main.rs:1184:13:1184:16 | &... | &T | main.rs:1168:5:1168:13 | S |
1507+
| main.rs:1184:13:1184:16 | &... | &T.&T | file://:0:0:0:0 | & |
1508+
| main.rs:1184:13:1184:16 | &... | &T.&T.&T | file://:0:0:0:0 | & |
1509+
| main.rs:1184:13:1184:16 | &... | &T.&T.&T.&T | main.rs:1168:5:1168:13 | S |
14781510
| main.rs:1184:14:1184:16 | &... | | file://:0:0:0:0 | & |
1479-
| main.rs:1184:14:1184:16 | &... | &T | main.rs:1168:5:1168:13 | S |
1511+
| main.rs:1184:14:1184:16 | &... | | main.rs:1168:5:1168:13 | S |
1512+
| main.rs:1184:14:1184:16 | &... | &T | file://:0:0:0:0 | & |
1513+
| main.rs:1184:14:1184:16 | &... | &T.&T | file://:0:0:0:0 | & |
1514+
| main.rs:1184:14:1184:16 | &... | &T.&T.&T | main.rs:1168:5:1168:13 | S |
14801515
| main.rs:1184:15:1184:16 | &x | | file://:0:0:0:0 | & |
1481-
| main.rs:1184:15:1184:16 | &x | &T | main.rs:1168:5:1168:13 | S |
1516+
| main.rs:1184:15:1184:16 | &x | &T | file://:0:0:0:0 | & |
1517+
| main.rs:1184:15:1184:16 | &x | &T.&T | main.rs:1168:5:1168:13 | S |
14821518
| main.rs:1184:16:1184:16 | x | | file://:0:0:0:0 | & |
14831519
| main.rs:1184:16:1184:16 | x | &T | main.rs:1168:5:1168:13 | S |
14841520
| main.rs:1189:13:1189:13 | x | | main.rs:1168:5:1168:13 | S |
@@ -1494,15 +1530,23 @@ inferType
14941530
| main.rs:1192:15:1192:16 | &x | | file://:0:0:0:0 | & |
14951531
| main.rs:1192:15:1192:16 | &x | &T | main.rs:1168:5:1168:13 | S |
14961532
| main.rs:1192:16:1192:16 | x | | main.rs:1168:5:1168:13 | S |
1497-
| main.rs:1194:18:1194:24 | * ... | | {EXTERNAL LOCATION} | bool |
1533+
| main.rs:1194:13:1194:13 | n | | {EXTERNAL LOCATION} | bool |
1534+
| main.rs:1194:17:1194:24 | * ... | | {EXTERNAL LOCATION} | bool |
1535+
| main.rs:1194:18:1194:24 | * ... | | file://:0:0:0:0 | & |
1536+
| main.rs:1194:18:1194:24 | * ... | &T | {EXTERNAL LOCATION} | bool |
14981537
| main.rs:1194:19:1194:24 | &... | | file://:0:0:0:0 | & |
1499-
| main.rs:1194:19:1194:24 | &... | &T | {EXTERNAL LOCATION} | bool |
1538+
| main.rs:1194:19:1194:24 | &... | &T | file://:0:0:0:0 | & |
1539+
| main.rs:1194:19:1194:24 | &... | &T.&T | {EXTERNAL LOCATION} | bool |
15001540
| main.rs:1194:20:1194:24 | &true | | file://:0:0:0:0 | & |
15011541
| main.rs:1194:20:1194:24 | &true | &T | {EXTERNAL LOCATION} | bool |
15021542
| main.rs:1194:21:1194:24 | true | | {EXTERNAL LOCATION} | bool |
1543+
| main.rs:1198:13:1198:20 | mut flag | | main.rs:1157:5:1160:5 | MyFlag |
1544+
| main.rs:1198:24:1198:41 | ...::default(...) | | main.rs:1157:5:1160:5 | MyFlag |
15031545
| main.rs:1199:22:1199:30 | &mut flag | | file://:0:0:0:0 | & |
15041546
| main.rs:1199:22:1199:30 | &mut flag | &T | main.rs:1157:5:1160:5 | MyFlag |
1547+
| main.rs:1199:27:1199:30 | flag | | main.rs:1157:5:1160:5 | MyFlag |
15051548
| main.rs:1200:18:1200:23 | "{:?}\\n" | | {EXTERNAL LOCATION} | str |
1549+
| main.rs:1200:26:1200:29 | flag | | main.rs:1157:5:1160:5 | MyFlag |
15061550
| main.rs:1214:43:1217:5 | { ... } | | {EXTERNAL LOCATION} | Result |
15071551
| main.rs:1214:43:1217:5 | { ... } | E | main.rs:1207:5:1208:14 | S1 |
15081552
| main.rs:1214:43:1217:5 | { ... } | T | main.rs:1207:5:1208:14 | S1 |

0 commit comments

Comments
 (0)