Skip to content

Commit 0c7b1d0

Browse files
committed
wip
1 parent a081acd commit 0c7b1d0

File tree

4 files changed

+58
-9
lines changed

4 files changed

+58
-9
lines changed

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

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2593,21 +2593,32 @@ private Type inferMethodCallTypeSelf(
25932593
apos.isSelf()
25942594
)
25952595
or
2596+
// adjust for implicit borrow
25962597
exists(TypePath path0, BorrowKind borrow0 |
25972598
result = inferMethodCallTypeSelf(n, derefChain, borrow0, path0) and
2598-
// adjust for implicit borrow
25992599
path0.isCons(borrow0.getRefType().getPositionalTypeParameter(0), path) and
26002600
borrow.isNoBorrow()
26012601
)
26022602
or
2603-
exists(TypePath path0 |
2604-
result = inferMethodCallTypeSelf(n, derefChain, borrow, path0) and
2603+
// adjust for implicit deref
2604+
exists(
2605+
DerefChain derefChain0, Type t0, TypePath path0, DerefImplItemNode impl, Type selfType,
2606+
TypePath selfPath
2607+
|
2608+
t0 = inferMethodCallTypeSelf(n, derefChain0, borrow, path0) and
2609+
derefChain0.isCons(impl, derefChain) and
26052610
borrow.isNoBorrow() and
2606-
// adjust for implicit deref
2607-
exists(DerefImplItemNode impl |
2608-
impl.isRefImpl() and
2609-
derefChain = DerefChain::singleton(impl) and
2610-
path = TypePath::cons(getRefTypeParameter(), path0)
2611+
selfType = impl.resolveSelfParamTypeStrippedAt(selfPath)
2612+
|
2613+
result = selfType and
2614+
path = selfPath and
2615+
not result instanceof TypeParameter
2616+
or
2617+
exists(TypeParameter tp, TypePath pathToTypeParam, TypePath suffix |
2618+
impl.returnTypeStrippedMentionsTypeParameterAt(tp, pathToTypeParam) and
2619+
path0 = pathToTypeParam.appendInverse(suffix) and
2620+
result = t0 and
2621+
path = selfPath.append(suffix)
26112622
)
26122623
)
26132624
}

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

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
private import rust
44
private import codeql.rust.internal.PathResolution
5+
private import codeql.rust.internal.Type
6+
private import codeql.rust.internal.TypeInference
7+
private import codeql.rust.internal.TypeMention
58
private import codeql.rust.elements.internal.generated.Raw
69
private import codeql.rust.elements.internal.generated.Synth
710
private import codeql.rust.frameworks.stdlib.Stdlib
@@ -27,6 +30,35 @@ class DerefImplItemNode extends ImplItemNode {
2730
*/
2831
predicate isRefImpl() { this.resolveSelfTyBuiltin() instanceof Builtins::RefType }
2932

33+
/** Gets the `deref` function in this `Deref` impl block. */
34+
Function getDerefFunction() { result = this.getAssocItem("deref") }
35+
36+
private SelfParam getSelfParam() { result = this.getDerefFunction().getSelfParam() }
37+
38+
/**
39+
* Resolves the type of of the `self` parameter inside the `deref` function,
40+
* stripped of the leading `&`.
41+
*/
42+
pragma[nomagic]
43+
Type resolveSelfParamTypeStrippedAt(TypePath path) {
44+
exists(TypePath path0 |
45+
result = getSelfParamTypeMention(this.getSelfParam()).resolveTypeAt(path0) and
46+
path0.isCons(getRefSharedTypeParameter(), path)
47+
)
48+
}
49+
50+
/**
51+
* Holds if the return type of the `deref` function, stripped of the leading `&`,
52+
* mentions type parameter `tp` at `path`.
53+
*/
54+
pragma[nomagic]
55+
predicate returnTypeStrippedMentionsTypeParameterAt(TypeParameter tp, TypePath path) {
56+
exists(TypePath path0 |
57+
tp = getReturnTypeMention(this.getDerefFunction()).resolveTypeAt(path0) and
58+
path0.isCons(getRefSharedTypeParameter(), path)
59+
)
60+
}
61+
3062
/** Gets an internal unique ID used to identify this block amongst all `Deref` impl blocks. */
3163
int getId() { idOfRaw(Synth::convertAstNodeToRaw(this), result) }
3264
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ fn implicit_dereference() {
111111
let z = MySmartPointer { value: S(0i64) };
112112
let z_ = z.foo(); // $ target=foo type=z_:TRef.i64
113113

114-
let v = Vec::new(); // $ target=new $ MISSING: type=v:T.i32
114+
let v = Vec::new(); // $ target=new type=v:T.i32
115115
let mut x = MySmartPointer { value: v };
116116
x.push(0); // $ target=push
117117
}

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5285,19 +5285,25 @@ inferType
52855285
| dereference.rs:112:14:112:20 | z.foo() | TRef | {EXTERNAL LOCATION} | i64 |
52865286
| dereference.rs:114:9:114:9 | v | | {EXTERNAL LOCATION} | Vec |
52875287
| dereference.rs:114:9:114:9 | v | A | {EXTERNAL LOCATION} | Global |
5288+
| dereference.rs:114:9:114:9 | v | T | {EXTERNAL LOCATION} | i32 |
52885289
| dereference.rs:114:13:114:22 | ...::new(...) | | {EXTERNAL LOCATION} | Vec |
52895290
| dereference.rs:114:13:114:22 | ...::new(...) | A | {EXTERNAL LOCATION} | Global |
5291+
| dereference.rs:114:13:114:22 | ...::new(...) | T | {EXTERNAL LOCATION} | i32 |
52905292
| dereference.rs:115:13:115:13 | x | | dereference.rs:18:1:20:1 | MySmartPointer |
52915293
| dereference.rs:115:13:115:13 | x | T | {EXTERNAL LOCATION} | Vec |
52925294
| dereference.rs:115:13:115:13 | x | T.A | {EXTERNAL LOCATION} | Global |
5295+
| dereference.rs:115:13:115:13 | x | T.T | {EXTERNAL LOCATION} | i32 |
52935296
| dereference.rs:115:17:115:43 | MySmartPointer {...} | | dereference.rs:18:1:20:1 | MySmartPointer |
52945297
| dereference.rs:115:17:115:43 | MySmartPointer {...} | T | {EXTERNAL LOCATION} | Vec |
52955298
| dereference.rs:115:17:115:43 | MySmartPointer {...} | T.A | {EXTERNAL LOCATION} | Global |
5299+
| dereference.rs:115:17:115:43 | MySmartPointer {...} | T.T | {EXTERNAL LOCATION} | i32 |
52965300
| dereference.rs:115:41:115:41 | v | | {EXTERNAL LOCATION} | Vec |
52975301
| dereference.rs:115:41:115:41 | v | A | {EXTERNAL LOCATION} | Global |
5302+
| dereference.rs:115:41:115:41 | v | T | {EXTERNAL LOCATION} | i32 |
52985303
| dereference.rs:116:5:116:5 | x | | dereference.rs:18:1:20:1 | MySmartPointer |
52995304
| dereference.rs:116:5:116:5 | x | T | {EXTERNAL LOCATION} | Vec |
53005305
| dereference.rs:116:5:116:5 | x | T.A | {EXTERNAL LOCATION} | Global |
5306+
| dereference.rs:116:5:116:5 | x | T.T | {EXTERNAL LOCATION} | i32 |
53015307
| dereference.rs:116:5:116:13 | x.push(...) | | {EXTERNAL LOCATION} | () |
53025308
| dereference.rs:116:12:116:12 | 0 | | {EXTERNAL LOCATION} | i32 |
53035309
| dereference.rs:143:19:151:5 | { ... } | | {EXTERNAL LOCATION} | () |

0 commit comments

Comments
 (0)