Skip to content

Commit 99b0d0c

Browse files
committed
wip
1 parent 8de4111 commit 99b0d0c

File tree

2 files changed

+157
-53
lines changed

2 files changed

+157
-53
lines changed

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

Lines changed: 131 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1611,25 +1611,21 @@ private module MethodResolution {
16111611
}
16121612

16131613
/**
1614-
* Same as `getACandidateReceiverTypeAt`, but with traits substituted in for types
1615-
* with trait bounds.
1614+
* Same as `getACandidateReceiverTypeAt`, but excludes pseudo types `!` and `unknown`.
16161615
*/
16171616
pragma[nomagic]
1618-
Type getACandidateReceiverTypeAtSubstituteLookupTraits(
1619-
string derefChain, BorrowKind borrow, TypePath path
1620-
) {
1621-
result = substituteLookupTraits(this.getACandidateReceiverTypeAt(derefChain, borrow, path))
1617+
Type getANonPseudoCandidateReceiverTypeAt(string derefChain, BorrowKind borrow, TypePath path) {
1618+
result = this.getACandidateReceiverTypeAt(derefChain, borrow, path) and
1619+
result != TNeverType() and
1620+
result != TUnknownType()
16221621
}
16231622

16241623
pragma[nomagic]
16251624
private Type getComplexStrippedType(
16261625
string derefChain, BorrowKind borrow, TypePath strippedTypePath
16271626
) {
1628-
result =
1629-
this.getACandidateReceiverTypeAtSubstituteLookupTraits(derefChain, borrow, strippedTypePath) and
1630-
isComplexRootStripped(strippedTypePath, result) and
1631-
result != TNeverType() and
1632-
result != TUnknownType()
1627+
result = this.getANonPseudoCandidateReceiverTypeAt(derefChain, borrow, strippedTypePath) and
1628+
isComplexRootStripped(strippedTypePath, result)
16331629
}
16341630

16351631
bindingset[derefChain, borrow, strippedTypePath, strippedType]
@@ -1667,22 +1663,58 @@ private module MethodResolution {
16671663
)
16681664
}
16691665

1666+
// forex using recursion
1667+
pragma[nomagic]
1668+
private predicate hasNoCompatibleTargetNoBorrowToIndex(
1669+
string derefChain, TypePath strippedTypePath, Type strippedType, int n
1670+
) {
1671+
(
1672+
this.supportsAutoDerefAndBorrow()
1673+
or
1674+
// needed for the `hasNoCompatibleTarget` check in
1675+
// `ReceiverSatisfiesBlanketLikeConstraintInput::hasBlanketCandidate`
1676+
derefChain = ""
1677+
) and
1678+
strippedType = this.getComplexStrippedType(derefChain, TNoBorrowKind(), strippedTypePath) and
1679+
n = -1
1680+
or
1681+
this.hasNoCompatibleTargetNoBorrowToIndex(derefChain, strippedTypePath, strippedType, n - 1) and
1682+
exists(Type t | t = getNthLookupType(strippedType, n) |
1683+
this.hasNoCompatibleTargetCheck(derefChain, TNoBorrowKind(), strippedTypePath, t)
1684+
)
1685+
}
1686+
16701687
/**
16711688
* Holds if the candidate receiver type represented by `derefChain` does not
16721689
* have a matching method target.
16731690
*/
16741691
pragma[nomagic]
16751692
predicate hasNoCompatibleTargetNoBorrow(string derefChain) {
1693+
exists(Type strippedType |
1694+
this.hasNoCompatibleTargetNoBorrowToIndex(derefChain, _, strippedType,
1695+
getLastLookupTypeIndex(strippedType))
1696+
)
1697+
}
1698+
1699+
// forex using recursion
1700+
pragma[nomagic]
1701+
private predicate hasNoCompatibleNonBlanketTargetNoBorrowToIndex(
1702+
string derefChain, TypePath strippedTypePath, Type strippedType, int n
1703+
) {
16761704
(
16771705
this.supportsAutoDerefAndBorrow()
16781706
or
16791707
// needed for the `hasNoCompatibleTarget` check in
16801708
// `ReceiverSatisfiesBlanketLikeConstraintInput::hasBlanketCandidate`
16811709
derefChain = ""
16821710
) and
1683-
exists(TypePath strippedTypePath, Type strippedType |
1684-
strippedType = this.getComplexStrippedType(derefChain, TNoBorrowKind(), strippedTypePath) and
1685-
this.hasNoCompatibleTargetCheck(derefChain, TNoBorrowKind(), strippedTypePath, strippedType)
1711+
strippedType = this.getComplexStrippedType(derefChain, TNoBorrowKind(), strippedTypePath) and
1712+
n = -1
1713+
or
1714+
this.hasNoCompatibleNonBlanketTargetNoBorrowToIndex(derefChain, strippedTypePath,
1715+
strippedType, n - 1) and
1716+
exists(Type t | t = getNthLookupType(strippedType, n) |
1717+
this.hasNoCompatibleNonBlanketTargetCheck(derefChain, TNoBorrowKind(), strippedTypePath, t)
16861718
)
16871719
}
16881720

@@ -1692,17 +1724,26 @@ private module MethodResolution {
16921724
*/
16931725
pragma[nomagic]
16941726
predicate hasNoCompatibleNonBlanketTargetNoBorrow(string derefChain) {
1695-
(
1696-
this.supportsAutoDerefAndBorrow()
1697-
or
1698-
// needed for the `hasNoCompatibleTarget` check in
1699-
// `ReceiverSatisfiesBlanketLikeConstraintInput::hasBlanketCandidate`
1700-
derefChain = ""
1701-
) and
1702-
exists(TypePath strippedTypePath, Type strippedType |
1703-
strippedType = this.getComplexStrippedType(derefChain, TNoBorrowKind(), strippedTypePath) and
1704-
this.hasNoCompatibleNonBlanketTargetCheck(derefChain, TNoBorrowKind(), strippedTypePath,
1705-
strippedType)
1727+
exists(Type strippedType |
1728+
this.hasNoCompatibleNonBlanketTargetNoBorrowToIndex(derefChain, _, strippedType,
1729+
getLastLookupTypeIndex(strippedType))
1730+
)
1731+
}
1732+
1733+
// forex using recursion
1734+
pragma[nomagic]
1735+
private predicate hasNoCompatibleTargetSharedBorrowToIndex(
1736+
string derefChain, TypePath strippedTypePath, Type strippedType, int n
1737+
) {
1738+
this.hasNoCompatibleTargetNoBorrow(derefChain) and
1739+
strippedType = this.getComplexStrippedType(derefChain, TSharedBorrowKind(), strippedTypePath) and
1740+
n = -1
1741+
or
1742+
this.hasNoCompatibleTargetSharedBorrowToIndex(derefChain, strippedTypePath, strippedType,
1743+
n - 1) and
1744+
exists(Type t | t = getNthLookupType(strippedType, n) |
1745+
this.hasNoCompatibleNonBlanketLikeTargetCheck(derefChain, TSharedBorrowKind(),
1746+
strippedTypePath, t)
17061747
)
17071748
}
17081749

@@ -1712,12 +1753,25 @@ private module MethodResolution {
17121753
*/
17131754
pragma[nomagic]
17141755
predicate hasNoCompatibleTargetSharedBorrow(string derefChain) {
1715-
exists(TypePath strippedTypePath, Type strippedType |
1716-
this.hasNoCompatibleTargetNoBorrow(derefChain) and
1717-
strippedType =
1718-
this.getComplexStrippedType(derefChain, TSharedBorrowKind(), strippedTypePath) and
1719-
this.hasNoCompatibleNonBlanketLikeTargetCheck(derefChain, TSharedBorrowKind(),
1720-
strippedTypePath, strippedType)
1756+
exists(Type strippedType |
1757+
this.hasNoCompatibleTargetSharedBorrowToIndex(derefChain, _, strippedType,
1758+
getLastLookupTypeIndex(strippedType))
1759+
)
1760+
}
1761+
1762+
// forex using recursion
1763+
pragma[nomagic]
1764+
private predicate hasNoCompatibleTargetMutBorrowToIndex(
1765+
string derefChain, TypePath strippedTypePath, Type strippedType, int n
1766+
) {
1767+
this.hasNoCompatibleTargetSharedBorrow(derefChain) and
1768+
strippedType = this.getComplexStrippedType(derefChain, TMutBorrowKind(), strippedTypePath) and
1769+
n = -1
1770+
or
1771+
this.hasNoCompatibleTargetMutBorrowToIndex(derefChain, strippedTypePath, strippedType, n - 1) and
1772+
exists(Type t | t = getNthLookupType(strippedType, n) |
1773+
this.hasNoCompatibleNonBlanketLikeTargetCheck(derefChain, TMutBorrowKind(),
1774+
strippedTypePath, t)
17211775
)
17221776
}
17231777

@@ -1727,11 +1781,26 @@ private module MethodResolution {
17271781
*/
17281782
pragma[nomagic]
17291783
predicate hasNoCompatibleTargetMutBorrow(string derefChain) {
1730-
exists(TypePath strippedTypePath, Type strippedType |
1731-
this.hasNoCompatibleTargetSharedBorrow(derefChain) and
1732-
strippedType = this.getComplexStrippedType(derefChain, TMutBorrowKind(), strippedTypePath) and
1733-
this.hasNoCompatibleNonBlanketLikeTargetCheck(derefChain, TMutBorrowKind(),
1734-
strippedTypePath, strippedType)
1784+
exists(Type strippedType |
1785+
this.hasNoCompatibleTargetMutBorrowToIndex(derefChain, _, strippedType,
1786+
getLastLookupTypeIndex(strippedType))
1787+
)
1788+
}
1789+
1790+
// forex using recursion
1791+
pragma[nomagic]
1792+
private predicate hasNoCompatibleNonBlanketTargetSharedBorrowToIndex(
1793+
string derefChain, TypePath strippedTypePath, Type strippedType, int n
1794+
) {
1795+
this.hasNoCompatibleTargetNoBorrow(derefChain) and
1796+
strippedType = this.getComplexStrippedType(derefChain, TSharedBorrowKind(), strippedTypePath) and
1797+
n = -1
1798+
or
1799+
this.hasNoCompatibleNonBlanketTargetSharedBorrowToIndex(derefChain, strippedTypePath,
1800+
strippedType, n - 1) and
1801+
exists(Type t | t = getNthLookupType(strippedType, n) |
1802+
this.hasNoCompatibleNonBlanketTargetCheck(derefChain, TSharedBorrowKind(), strippedTypePath,
1803+
t)
17351804
)
17361805
}
17371806

@@ -1741,12 +1810,25 @@ private module MethodResolution {
17411810
*/
17421811
pragma[nomagic]
17431812
predicate hasNoCompatibleNonBlanketTargetSharedBorrow(string derefChain) {
1744-
exists(TypePath strippedTypePath, Type strippedType |
1745-
this.hasNoCompatibleTargetNoBorrow(derefChain) and
1746-
strippedType =
1747-
this.getComplexStrippedType(derefChain, TSharedBorrowKind(), strippedTypePath) and
1748-
this.hasNoCompatibleNonBlanketTargetCheck(derefChain, TSharedBorrowKind(), strippedTypePath,
1749-
strippedType)
1813+
exists(Type strippedType |
1814+
this.hasNoCompatibleNonBlanketTargetSharedBorrowToIndex(derefChain, _, strippedType,
1815+
getLastLookupTypeIndex(strippedType))
1816+
)
1817+
}
1818+
1819+
// forex using recursion
1820+
pragma[nomagic]
1821+
private predicate hasNoCompatibleNonBlanketTargetMutBorrowToIndex(
1822+
string derefChain, TypePath strippedTypePath, Type strippedType, int n
1823+
) {
1824+
this.hasNoCompatibleNonBlanketTargetSharedBorrow(derefChain) and
1825+
strippedType = this.getComplexStrippedType(derefChain, TMutBorrowKind(), strippedTypePath) and
1826+
n = -1
1827+
or
1828+
this.hasNoCompatibleNonBlanketTargetMutBorrowToIndex(derefChain, strippedTypePath,
1829+
strippedType, n - 1) and
1830+
exists(Type t | t = getNthLookupType(strippedType, n) |
1831+
this.hasNoCompatibleNonBlanketTargetCheck(derefChain, TMutBorrowKind(), strippedTypePath, t)
17501832
)
17511833
}
17521834

@@ -1756,11 +1838,9 @@ private module MethodResolution {
17561838
*/
17571839
pragma[nomagic]
17581840
predicate hasNoCompatibleNonBlanketTargetMutBorrow(string derefChain) {
1759-
exists(TypePath strippedTypePath, Type strippedType |
1760-
this.hasNoCompatibleNonBlanketTargetSharedBorrow(derefChain) and
1761-
strippedType = this.getComplexStrippedType(derefChain, TMutBorrowKind(), strippedTypePath) and
1762-
this.hasNoCompatibleNonBlanketTargetCheck(derefChain, TMutBorrowKind(), strippedTypePath,
1763-
strippedType)
1841+
exists(Type strippedType |
1842+
this.hasNoCompatibleNonBlanketTargetMutBorrowToIndex(derefChain, _, strippedType,
1843+
getLastLookupTypeIndex(strippedType))
17641844
)
17651845
}
17661846

@@ -1999,9 +2079,8 @@ private module MethodResolution {
19992079
MethodCall getMethodCall() { result = mc_ }
20002080

20012081
Type getTypeAt(TypePath path) {
2002-
result = mc_.getACandidateReceiverTypeAtSubstituteLookupTraits(derefChain, borrow, path) and
2003-
not result = TNeverType() and
2004-
not result = TUnknownType()
2082+
result =
2083+
substituteLookupTraits(mc_.getANonPseudoCandidateReceiverTypeAt(derefChain, borrow, path))
20052084
}
20062085

20072086
pragma[nomagic]
@@ -3918,8 +3997,8 @@ private module Debug {
39183997
Locatable getRelevantLocatable() {
39193998
exists(string filepath, int startline, int startcolumn, int endline, int endcolumn |
39203999
result.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) and
3921-
filepath.matches("%/sqlx.rs") and
3922-
startline = [56 .. 60]
4000+
filepath.matches("%/multi_buffer.rs") and
4001+
startline = 3707
39234002
)
39244003
}
39254004

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

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ class AssocFunctionType extends MkAssocFunctionType {
194194
Location getLocation() { result = this.getTypeMention().getLocation() }
195195
}
196196

197+
pragma[nomagic]
197198
private Trait getALookupTrait(Type t) {
198199
result = t.(TypeParamTypeParameter).getTypeParam().(TypeParamItemNode).resolveABound()
199200
or
@@ -208,14 +209,38 @@ private Trait getALookupTrait(Type t) {
208209
* Gets the type obtained by substituting in relevant traits in which to do function
209210
* lookup, or `t` itself when no such trait exist.
210211
*/
211-
bindingset[t]
212+
pragma[nomagic]
212213
Type substituteLookupTraits(Type t) {
213214
not exists(getALookupTrait(t)) and
214215
result = t
215216
or
216217
result = TTrait(getALookupTrait(t))
217218
}
218219

220+
/**
221+
* Gets the `n`th `substituteLookupTraits` type for `t`, per some abitrary order.
222+
*/
223+
pragma[nomagic]
224+
Type getNthLookupType(Type t, int n) {
225+
not exists(getALookupTrait(t)) and
226+
result = t and
227+
n = 0
228+
or
229+
result =
230+
TTrait(rank[n + 1](Trait trait, int i |
231+
trait = getALookupTrait(t) and
232+
i = idOfTypeParameterAstNode(trait)
233+
|
234+
trait order by i
235+
))
236+
}
237+
238+
/**
239+
* Gets the index of the last `substituteLookupTraits` type for `t`.
240+
*/
241+
pragma[nomagic]
242+
int getLastLookupTypeIndex(Type t) { result = max(int n | exists(getNthLookupType(t, n))) }
243+
219244
/**
220245
* A wrapper around `IsInstantiationOf` which ensures to substitute in lookup
221246
* traits when checking whether argument types are instantiations of function

0 commit comments

Comments
 (0)