Skip to content

Commit ee85c9e

Browse files
committed
Address review comments
1 parent fd309d6 commit ee85c9e

File tree

3 files changed

+44
-47
lines changed

3 files changed

+44
-47
lines changed

rust/ql/lib/codeql/rust/frameworks/stdlib/Stdlib.qll

Lines changed: 28 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,34 @@ private class StartswithCall extends Path::SafeAccessCheck::Range, MethodCall {
2222
}
2323
}
2424

25+
/**
26+
* A flow summary for the [reflexive implementation of the `From` trait][1].
27+
*
28+
* Blanket implementations currently don't have a canonical path, so we cannot
29+
* use models-as-data for this model.
30+
*
31+
* [1]: https://doc.rust-lang.org/std/convert/trait.From.html#impl-From%3CT%3E-for-T
32+
*/
33+
private class ReflexiveFrom extends SummarizedCallable::Range {
34+
ReflexiveFrom() {
35+
exists(ImplItemNode impl |
36+
impl.resolveTraitTy().(Trait).getCanonicalPath() = "core::convert::From" and
37+
this = impl.getAssocItem("from") and
38+
resolvePath(this.getParam(0).getTypeRepr().(PathTypeRepr).getPath()) =
39+
impl.getBlanketImplementationTypeParam()
40+
)
41+
}
42+
43+
override predicate propagatesFlow(
44+
string input, string output, boolean preservesValue, string model
45+
) {
46+
input = "Argument[0]" and
47+
output = "ReturnValue" and
48+
preservesValue = true and
49+
model = "ReflexiveFrom"
50+
}
51+
}
52+
2553
/**
2654
* The [`Option` enum][1].
2755
*
@@ -300,30 +328,3 @@ class Vec extends Struct {
300328
/** Gets the type parameter representing the element type. */
301329
TypeParam getElementTypeParam() { result = this.getGenericParamList().getTypeParam(0) }
302330
}
303-
304-
// Blanket implementations currently don't have a canonical path, so we cannot
305-
// use models-as-data for this model.
306-
private class ReflexiveFrom extends SummarizedCallable::Range {
307-
ReflexiveFrom() {
308-
exists(ImplItemNode impl |
309-
impl.resolveTraitTy().(Trait).getCanonicalPath() = "core::convert::From" and
310-
this = impl.getAnAssocItem() and
311-
impl.isBlanketImplementation() and
312-
this.getParam(0)
313-
.getTypeRepr()
314-
.(TypeMention)
315-
.resolveType()
316-
.(TypeParamTypeParameter)
317-
.getTypeParam() = impl.getTypeParam(0)
318-
)
319-
}
320-
321-
override predicate propagatesFlow(
322-
string input, string output, boolean preservesValue, string model
323-
) {
324-
input = "Argument[0]" and
325-
output = "ReturnValue" and
326-
preservesValue = true and
327-
model = "ReflexiveFrom"
328-
}
329-
}

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

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,12 @@ private predicate implSiblingCandidate(
3535
rootType = selfTy.resolveType()
3636
}
3737

38+
pragma[nomagic]
39+
private predicate blanketImplSiblingCandidate(ImplItemNode impl, Trait trait) {
40+
impl.isBlanketImplementation() and
41+
trait = impl.resolveTraitTy()
42+
}
43+
3844
/**
3945
* Holds if `impl1` and `impl2` are a sibling implementations of `trait`. We
4046
* consider implementations to be siblings if they implement the same trait for
@@ -44,8 +50,7 @@ private predicate implSiblingCandidate(
4450
*/
4551
pragma[inline]
4652
private predicate implSiblings(TraitItemNode trait, Impl impl1, Impl impl2) {
47-
exists(Type rootType, TypeMention selfTy1, TypeMention selfTy2 |
48-
impl1 != impl2 and
53+
exists(Type rootType, TypeMention selfTy1, TypeMention selfTy2 | impl1 != impl2 |
4954
implSiblingCandidate(impl1, trait, rootType, selfTy1) and
5055
implSiblingCandidate(impl2, trait, rootType, selfTy2) and
5156
// In principle the second conjunct below should be superflous, but we still
@@ -55,29 +60,18 @@ private predicate implSiblings(TraitItemNode trait, Impl impl1, Impl impl2) {
5560
// correct.
5661
typeMentionEqual(selfTy1, selfTy2) and
5762
typeMentionEqual(selfTy2, selfTy1)
63+
or
64+
blanketImplSiblingCandidate(impl1, trait) and
65+
blanketImplSiblingCandidate(impl2, trait)
5866
)
5967
}
6068

61-
pragma[nomagic]
62-
private predicate isBlanketImpl(ImplItemNode impl, Trait trait) {
63-
impl.isBlanketImplementation() and
64-
trait = impl.resolveTraitTy()
65-
}
66-
6769
/**
6870
* Holds if `impl` is an implementation of `trait` and if another implementation
6971
* exists for the same type.
7072
*/
7173
pragma[nomagic]
72-
private predicate implHasSibling(ImplItemNode impl, Trait trait) {
73-
implSiblings(trait, impl, _)
74-
or
75-
exists(ImplItemNode other |
76-
isBlanketImpl(impl, trait) and
77-
isBlanketImpl(other, trait) and
78-
impl != other
79-
)
80-
}
74+
private predicate implHasSibling(ImplItemNode impl, Trait trait) { implSiblings(trait, impl, _) }
8175

8276
/**
8377
* Holds if type parameter `tp` of `trait` occurs in the function `f` with the name

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

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1293,7 +1293,7 @@ private class BorrowKind extends TBorrowKind {
12931293
// a constrained type parameter; we should be checking the constraints in this case
12941294
private predicate typeCanBeUsedForDisambiguation(Type t) {
12951295
not t instanceof TypeParameter or
1296-
t.(TypeParamTypeParameter).getTypeParam() = any(TypeParam tp | not exists(tp.getATypeBound()))
1296+
t.(TypeParamTypeParameter).getTypeParam() = any(TypeParam tp | not tp.hasTypeBound())
12971297
}
12981298

12991299
/**
@@ -2241,7 +2241,8 @@ private module MethodResolution {
22412241
methodCallBlanketLikeCandidate(mc, _, impl, _, blanketPath, blanketTypeParam) and
22422242
// Only apply blanket implementations when no other implementations are possible;
22432243
// this is to account for codebases that use the (unstable) specialization feature
2244-
// (https://rust-lang.github.io/rfcs/1210-impl-specialization.html)
2244+
// (https://rust-lang.github.io/rfcs/1210-impl-specialization.html), as well as
2245+
// cases where our blanket implementation filtering is not precise enough.
22452246
(mcc.hasNoCompatibleNonBlanketTarget() or not impl.isBlanketImplementation())
22462247
|
22472248
borrow.isNoBorrow()
@@ -2878,7 +2879,8 @@ private module NonMethodResolution {
28782879
fc.resolveCallTargetBlanketLikeCandidate(impl, pos, blanketPath, blanketTypeParam) and
28792880
// Only apply blanket implementations when no other implementations are possible;
28802881
// this is to account for codebases that use the (unstable) specialization feature
2881-
// (https://rust-lang.github.io/rfcs/1210-impl-specialization.html)
2882+
// (https://rust-lang.github.io/rfcs/1210-impl-specialization.html), as well as
2883+
// cases where our blanket implementation filtering is not precise enough.
28822884
(fc.hasNoCompatibleNonBlanketTarget() or not impl.isBlanketImplementation())
28832885
)
28842886
}

0 commit comments

Comments
 (0)