Skip to content

Commit f76d85c

Browse files
committed
Address review comments
1 parent fd309d6 commit f76d85c

File tree

3 files changed

+56
-56
lines changed

3 files changed

+56
-56
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: 23 additions & 26 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,40 +50,31 @@ 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
49-
implSiblingCandidate(impl1, trait, rootType, selfTy1) and
50-
implSiblingCandidate(impl2, trait, rootType, selfTy2) and
51-
// In principle the second conjunct below should be superflous, but we still
52-
// have ill-formed type mentions for types that we don't understand. For
53-
// those checking both directions restricts further. Note also that we check
54-
// syntactic equality, whereas equality up to renaming would be more
55-
// correct.
56-
typeMentionEqual(selfTy1, selfTy2) and
57-
typeMentionEqual(selfTy2, selfTy1)
53+
impl1 != impl2 and
54+
(
55+
exists(Type rootType, TypeMention selfTy1, TypeMention selfTy2 |
56+
implSiblingCandidate(impl1, trait, rootType, selfTy1) and
57+
implSiblingCandidate(impl2, trait, rootType, selfTy2) and
58+
// In principle the second conjunct below should be superflous, but we still
59+
// have ill-formed type mentions for types that we don't understand. For
60+
// those checking both directions restricts further. Note also that we check
61+
// syntactic equality, whereas equality up to renaming would be more
62+
// correct.
63+
typeMentionEqual(selfTy1, selfTy2) and
64+
typeMentionEqual(selfTy2, selfTy1)
65+
)
66+
or
67+
blanketImplSiblingCandidate(impl1, trait) and
68+
blanketImplSiblingCandidate(impl2, trait)
5869
)
5970
}
6071

61-
pragma[nomagic]
62-
private predicate isBlanketImpl(ImplItemNode impl, Trait trait) {
63-
impl.isBlanketImplementation() and
64-
trait = impl.resolveTraitTy()
65-
}
66-
6772
/**
6873
* Holds if `impl` is an implementation of `trait` and if another implementation
6974
* exists for the same type.
7075
*/
7176
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-
}
77+
private predicate implHasSibling(ImplItemNode impl, Trait trait) { implSiblings(trait, impl, _) }
8178

8279
/**
8380
* 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)