Skip to content

Commit 9a2bb3e

Browse files
committed
Rust: Model String -> str implicit conversion in type inference
1 parent 31770ed commit 9a2bb3e

File tree

1 file changed

+20
-5
lines changed

1 file changed

+20
-5
lines changed

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

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1153,12 +1153,27 @@ private module MethodCall {
11531153

11541154
pragma[nomagic]
11551155
override Type getTypeAt(TypePath path) {
1156-
exists(TypePath path0 | result = inferType(super.getReceiver(), path0) |
1157-
path0.isCons(TRefTypeParameter(), path)
1156+
exists(TypePath path0, Type t0 |
1157+
t0 = inferType(super.getReceiver(), path0) and
1158+
(
1159+
path0.isCons(TRefTypeParameter(), path)
1160+
or
1161+
not path0.isCons(TRefTypeParameter(), _) and
1162+
not (path0.isEmpty() and result = TRefType()) and
1163+
path = path0
1164+
)
1165+
|
1166+
result = t0
11581167
or
1159-
not path0.isCons(TRefTypeParameter(), _) and
1160-
not (path0.isEmpty() and result = TRefType()) and
1161-
path = path0
1168+
// We do not yet model the `Deref` trait, so we hard-code the fact that
1169+
// `String` dereferences to `str` here. This allows us e.g. to resolve
1170+
// `x.parse::<usize>()` to the function `<core::str>::parse` when `x` has
1171+
// type `String`.
1172+
//
1173+
// See also https://doc.rust-lang.org/reference/expressions/method-call-expr.html#r-expr.method.autoref-deref
1174+
path.isEmpty() and
1175+
t0.(StructType).asItemNode().(Struct).getCanonicalPath() = "alloc::string::String" and
1176+
result.(StructType).asItemNode().(Struct).getCanonicalPath() = "core::str"
11621177
)
11631178
}
11641179
}

0 commit comments

Comments
 (0)