Skip to content

Commit 2f74251

Browse files
committed
wip7
1 parent 21d0384 commit 2f74251

3 files changed

Lines changed: 28 additions & 24 deletions

File tree

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

Lines changed: 19 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,9 @@ private module Input3 implements InputSig3 {
314314
n = c and
315315
result = c.getTypeRepr()
316316
)
317+
or
318+
coerceAnnotated(_, n) and
319+
result = n
317320
}
318321

319322
class Expr = Rust::Expr;
@@ -596,6 +599,11 @@ private module Input3 implements InputSig3 {
596599
not isPanicMacroCall(n2)
597600
or
598601
n1 = n2.(MacroPat).getMacroCall().getMacroCallExpansion()
602+
or
603+
// this step does not actually propagate type information from `n1` to `n2`, but
604+
// it allows for reverse propagation of type information from `n2` to `n1` in the
605+
// case where `n1` has an explicit unknown type
606+
coerceAnnotated(n1, n2)
599607
)
600608
)
601609
or
@@ -623,6 +631,7 @@ private module Input3 implements InputSig3 {
623631
)
624632
}
625633

634+
pragma[inline]
626635
Type inferType(AstNode n, TypePath path) {
627636
result = M3::inferType(n, path)
628637
or
@@ -660,10 +669,6 @@ private module Input3 implements InputSig3 {
660669
}
661670

662671
Type inferTypeTopDown(AstNode n, TypePath path) {
663-
result = inferTypeFromAnnotationTopDown(n, path)
664-
or
665-
result = inferClosureExprBodyTypeTopDown(n, path)
666-
or
667672
exists(FunctionPosition pos | not pos.isReturn() |
668673
result = inferConstructionType(n, pos, path)
669674
or
@@ -918,17 +923,17 @@ private Struct getRangeType(RangeExpr re) {
918923
result instanceof RangeToInclusiveStruct
919924
}
920925

926+
/**
927+
* Holds if `n` is a coercion site, and `tm` is a type annotation to which
928+
* the type of `n` must be coerced.
929+
*/
921930
pragma[nomagic]
922-
private Type inferTypeFromAnnotationTopDown(AstNode n, TypePath path) {
923-
// Normally, these are coercion sites, but in case a type is unknown we
924-
// allow for type information to flow from the type annotation.
925-
exists(TypeMention tm | result = tm.getTypeAt(path) |
926-
tm = any(LetStmt let | identLetStmt(let, _, n)).getTypeRepr()
927-
or
928-
tm = any(ClosureExpr ce | n = ce.getBody()).getRetType().getTypeRepr()
929-
or
930-
tm = getReturnTypeMention(any(Function f | n = f.getBody()))
931-
)
931+
private predicate coerceAnnotated(AstNode n, TypeMention tm) {
932+
tm = any(LetStmt let | identLetStmt(let, _, n)).getTypeRepr()
933+
or
934+
tm = any(ClosureExpr ce | n = ce.getBody()).getRetType().getTypeRepr()
935+
or
936+
tm = getReturnTypeMention(any(Function f | n = f.getBody()))
932937
}
933938

934939
pragma[nomagic]
@@ -3649,14 +3654,6 @@ private Type inferForLoopExprType(AstNode n, TypePath path) {
36493654
)
36503655
}
36513656

3652-
pragma[nomagic]
3653-
private Type inferClosureExprBodyTypeTopDown(AstNode n, TypePath path) {
3654-
exists(ClosureExpr ce |
3655-
n = ce.getClosureBody() and
3656-
result = inferType(ce, closureReturnPath().appendInverse(path))
3657-
)
3658-
}
3659-
36603657
pragma[nomagic]
36613658
private Type inferClosureExprType(ClosureExpr ce, TypePath path) {
36623659
path = TypePath::singleton(TDynTraitTypeParameter(_, any(FnTrait t).getTypeParam())) and

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
import rust
22
import utils.test.InlineExpectationsTest
33
import codeql.rust.internal.typeinference.Type
4+
import codeql.rust.internal.typeinference.TypeMention
45
import codeql.rust.internal.typeinference.TypeInference as TypeInference
56
import TypeInference
67

78
private predicate relevantNode(AstNode n) {
89
n.fromSource() and
910
not n.isFromMacroExpansion() and
1011
not n instanceof IdentPat and // avoid overlap in the output with the underlying `Name` node
11-
not n instanceof LiteralPat // avoid overlap in the output with the underlying `Literal` node
12+
not n instanceof LiteralPat and // avoid overlap in the output with the underlying `Literal` node
13+
(n instanceof TypeMention implies n instanceof SelfParam)
1214
}
1315

1416
query predicate inferCertainType(AstNode n, TypePath path, Type t) {

shared/typeinference/codeql/typeinference/internal/TypeInference.qll

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2213,7 +2213,12 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
22132213
* Gets an additional type parameter constraint for the given type parameter,
22142214
* which applies to this callable. For example, in Rust, a function can apply
22152215
* additional constraints on type parameters belonging to the `impl` block
2216-
* that the function is defined in.
2216+
* that the function is defined in:
2217+
*
2218+
* ```rust
2219+
* impl<T> MyThing<T> {
2220+
* fn foo(self) where T: MyTrait { ... }
2221+
* }
22172222
*/
22182223
TypeMention getAdditionalTypeParameterConstraint(TypeParameter tp);
22192224

0 commit comments

Comments
 (0)