@@ -7,6 +7,7 @@ private import PathResolution
77private import Type
88private import Type as T
99private import TypeMention
10+ private import typeinference.DerefChain
1011private import typeinference.FunctionType
1112private import typeinference.FunctionOverloading as FunctionOverloading
1213private import typeinference.BlanketImplementation as BlanketImplementation
@@ -1553,13 +1554,13 @@ private module MethodResolution {
15531554 * Same as `getACandidateReceiverTypeAt`, but without borrows.
15541555 */
15551556 pragma [ nomagic]
1556- Type getACandidateReceiverTypeAtNoBorrow ( string derefChain , TypePath path ) {
1557+ Type getACandidateReceiverTypeAtNoBorrow ( DerefChain derefChain , TypePath path ) {
15571558 result = this .getReceiverTypeAt ( path ) and
15581559 derefChain = ""
15591560 or
1560- exists ( ImplicitDeref :: DerefImplItemNode impl , string derefChain0 |
1561- result = ImplicitDeref:: getDereferencedCandidateReceiverType ( this , impl , derefChain0 , path ) and
1562- derefChain = derefChain0 + "." + impl . getId ( )
1561+ exists ( DerefImplItemNode impl , DerefChain suffix |
1562+ result = ImplicitDeref:: getDereferencedCandidateReceiverType ( this , impl , suffix , path ) and
1563+ derefChain = DerefChain :: cons ( impl , suffix )
15631564 )
15641565 }
15651566
@@ -1573,7 +1574,7 @@ private module MethodResolution {
15731574 */
15741575 pragma [ nomagic]
15751576 private predicate hasIncompatibleTarget (
1576- ImplOrTraitItemNode i , string derefChain , BorrowKind borrow , Type root
1577+ ImplOrTraitItemNode i , DerefChain derefChain , BorrowKind borrow , Type root
15771578 ) {
15781579 exists ( TypePath path |
15791580 ReceiverIsInstantiationOfSelfParam:: argIsNotInstantiationOf ( MkMethodCallCand ( this ,
@@ -1590,7 +1591,7 @@ private module MethodResolution {
15901591 */
15911592 pragma [ nomagic]
15921593 private predicate hasIncompatibleBlanketLikeTarget (
1593- ImplItemNode impl , string derefChain , BorrowKind borrow
1594+ ImplItemNode impl , DerefChain derefChain , BorrowKind borrow
15941595 ) {
15951596 ReceiverIsNotInstantiationOfBlanketLikeSelfParam:: argIsNotInstantiationOf ( MkMethodCallCand ( this ,
15961597 derefChain , borrow ) , impl , _, _)
@@ -1603,23 +1604,25 @@ private module MethodResolution {
16031604 * Same as `getACandidateReceiverTypeAt`, but excludes pseudo types `!` and `unknown`.
16041605 */
16051606 pragma [ nomagic]
1606- Type getANonPseudoCandidateReceiverTypeAt ( string derefChain , BorrowKind borrow , TypePath path ) {
1607+ Type getANonPseudoCandidateReceiverTypeAt (
1608+ DerefChain derefChain , BorrowKind borrow , TypePath path
1609+ ) {
16071610 result = this .getACandidateReceiverTypeAt ( derefChain , borrow , path ) and
16081611 result != TNeverType ( ) and
16091612 result != TUnknownType ( )
16101613 }
16111614
16121615 pragma [ nomagic]
16131616 private Type getComplexStrippedType (
1614- string derefChain , BorrowKind borrow , TypePath strippedTypePath
1617+ DerefChain derefChain , BorrowKind borrow , TypePath strippedTypePath
16151618 ) {
16161619 result = this .getANonPseudoCandidateReceiverTypeAt ( derefChain , borrow , strippedTypePath ) and
16171620 isComplexRootStripped ( strippedTypePath , result )
16181621 }
16191622
16201623 bindingset [ derefChain, borrow, strippedTypePath, strippedType]
16211624 private predicate hasNoCompatibleNonBlanketLikeTargetCheck (
1622- string derefChain , BorrowKind borrow , TypePath strippedTypePath , Type strippedType
1625+ DerefChain derefChain , BorrowKind borrow , TypePath strippedTypePath , Type strippedType
16231626 ) {
16241627 forall ( ImplOrTraitItemNode i |
16251628 methodCallNonBlanketCandidate ( this , _, i , _, strippedTypePath , strippedType )
@@ -1630,7 +1633,7 @@ private module MethodResolution {
16301633
16311634 bindingset [ derefChain, borrow, strippedTypePath, strippedType]
16321635 private predicate hasNoCompatibleTargetCheck (
1633- string derefChain , BorrowKind borrow , TypePath strippedTypePath , Type strippedType
1636+ DerefChain derefChain , BorrowKind borrow , TypePath strippedTypePath , Type strippedType
16341637 ) {
16351638 this .hasNoCompatibleNonBlanketLikeTargetCheck ( derefChain , borrow , strippedTypePath ,
16361639 strippedType ) and
@@ -1641,7 +1644,7 @@ private module MethodResolution {
16411644
16421645 bindingset [ derefChain, borrow, strippedTypePath, strippedType]
16431646 private predicate hasNoCompatibleNonBlanketTargetCheck (
1644- string derefChain , BorrowKind borrow , TypePath strippedTypePath , Type strippedType
1647+ DerefChain derefChain , BorrowKind borrow , TypePath strippedTypePath , Type strippedType
16451648 ) {
16461649 this .hasNoCompatibleNonBlanketLikeTargetCheck ( derefChain , borrow , strippedTypePath ,
16471650 strippedType ) and
@@ -1655,7 +1658,7 @@ private module MethodResolution {
16551658 // forex using recursion
16561659 pragma [ nomagic]
16571660 private predicate hasNoCompatibleTargetNoBorrowToIndex (
1658- string derefChain , TypePath strippedTypePath , Type strippedType , int n
1661+ DerefChain derefChain , TypePath strippedTypePath , Type strippedType , int n
16591662 ) {
16601663 (
16611664 this .supportsAutoDerefAndBorrow ( )
@@ -1678,7 +1681,7 @@ private module MethodResolution {
16781681 * have a matching method target.
16791682 */
16801683 pragma [ nomagic]
1681- predicate hasNoCompatibleTargetNoBorrow ( string derefChain ) {
1684+ predicate hasNoCompatibleTargetNoBorrow ( DerefChain derefChain ) {
16821685 exists ( Type strippedType |
16831686 this .hasNoCompatibleTargetNoBorrowToIndex ( derefChain , _, strippedType ,
16841687 getLastLookupTypeIndex ( strippedType ) )
@@ -1688,7 +1691,7 @@ private module MethodResolution {
16881691 // forex using recursion
16891692 pragma [ nomagic]
16901693 private predicate hasNoCompatibleNonBlanketTargetNoBorrowToIndex (
1691- string derefChain , TypePath strippedTypePath , Type strippedType , int n
1694+ DerefChain derefChain , TypePath strippedTypePath , Type strippedType , int n
16921695 ) {
16931696 (
16941697 this .supportsAutoDerefAndBorrow ( )
@@ -1712,7 +1715,7 @@ private module MethodResolution {
17121715 * a matching non-blanket method target.
17131716 */
17141717 pragma [ nomagic]
1715- predicate hasNoCompatibleNonBlanketTargetNoBorrow ( string derefChain ) {
1718+ predicate hasNoCompatibleNonBlanketTargetNoBorrow ( DerefChain derefChain ) {
17161719 exists ( Type strippedType |
17171720 this .hasNoCompatibleNonBlanketTargetNoBorrowToIndex ( derefChain , _, strippedType ,
17181721 getLastLookupTypeIndex ( strippedType ) )
@@ -1722,7 +1725,7 @@ private module MethodResolution {
17221725 // forex using recursion
17231726 pragma [ nomagic]
17241727 private predicate hasNoCompatibleTargetSharedBorrowToIndex (
1725- string derefChain , TypePath strippedTypePath , Type strippedType , int n
1728+ DerefChain derefChain , TypePath strippedTypePath , Type strippedType , int n
17261729 ) {
17271730 this .hasNoCompatibleTargetNoBorrow ( derefChain ) and
17281731 strippedType = this .getComplexStrippedType ( derefChain , TSharedBorrowKind ( ) , strippedTypePath ) and
@@ -1741,7 +1744,7 @@ private module MethodResolution {
17411744 * by a shared borrow, does not have a matching method target.
17421745 */
17431746 pragma [ nomagic]
1744- predicate hasNoCompatibleTargetSharedBorrow ( string derefChain ) {
1747+ predicate hasNoCompatibleTargetSharedBorrow ( DerefChain derefChain ) {
17451748 exists ( Type strippedType |
17461749 this .hasNoCompatibleTargetSharedBorrowToIndex ( derefChain , _, strippedType ,
17471750 getLastLookupTypeIndex ( strippedType ) )
@@ -1751,7 +1754,7 @@ private module MethodResolution {
17511754 // forex using recursion
17521755 pragma [ nomagic]
17531756 private predicate hasNoCompatibleTargetMutBorrowToIndex (
1754- string derefChain , TypePath strippedTypePath , Type strippedType , int n
1757+ DerefChain derefChain , TypePath strippedTypePath , Type strippedType , int n
17551758 ) {
17561759 this .hasNoCompatibleTargetSharedBorrow ( derefChain ) and
17571760 strippedType = this .getComplexStrippedType ( derefChain , TMutBorrowKind ( ) , strippedTypePath ) and
@@ -1769,7 +1772,7 @@ private module MethodResolution {
17691772 * by a `mut` borrow, does not have a matching method target.
17701773 */
17711774 pragma [ nomagic]
1772- predicate hasNoCompatibleTargetMutBorrow ( string derefChain ) {
1775+ predicate hasNoCompatibleTargetMutBorrow ( DerefChain derefChain ) {
17731776 exists ( Type strippedType |
17741777 this .hasNoCompatibleTargetMutBorrowToIndex ( derefChain , _, strippedType ,
17751778 getLastLookupTypeIndex ( strippedType ) )
@@ -1779,7 +1782,7 @@ private module MethodResolution {
17791782 // forex using recursion
17801783 pragma [ nomagic]
17811784 private predicate hasNoCompatibleNonBlanketTargetSharedBorrowToIndex (
1782- string derefChain , TypePath strippedTypePath , Type strippedType , int n
1785+ DerefChain derefChain , TypePath strippedTypePath , Type strippedType , int n
17831786 ) {
17841787 this .hasNoCompatibleTargetNoBorrow ( derefChain ) and
17851788 strippedType = this .getComplexStrippedType ( derefChain , TSharedBorrowKind ( ) , strippedTypePath ) and
@@ -1798,7 +1801,7 @@ private module MethodResolution {
17981801 * by a shared borrow, does not have a matching non-blanket method target.
17991802 */
18001803 pragma [ nomagic]
1801- predicate hasNoCompatibleNonBlanketTargetSharedBorrow ( string derefChain ) {
1804+ predicate hasNoCompatibleNonBlanketTargetSharedBorrow ( DerefChain derefChain ) {
18021805 exists ( Type strippedType |
18031806 this .hasNoCompatibleNonBlanketTargetSharedBorrowToIndex ( derefChain , _, strippedType ,
18041807 getLastLookupTypeIndex ( strippedType ) )
@@ -1808,7 +1811,7 @@ private module MethodResolution {
18081811 // forex using recursion
18091812 pragma [ nomagic]
18101813 private predicate hasNoCompatibleNonBlanketTargetMutBorrowToIndex (
1811- string derefChain , TypePath strippedTypePath , Type strippedType , int n
1814+ DerefChain derefChain , TypePath strippedTypePath , Type strippedType , int n
18121815 ) {
18131816 this .hasNoCompatibleNonBlanketTargetSharedBorrow ( derefChain ) and
18141817 strippedType = this .getComplexStrippedType ( derefChain , TMutBorrowKind ( ) , strippedTypePath ) and
@@ -1826,7 +1829,7 @@ private module MethodResolution {
18261829 * by a `mut` borrow, does not have a matching non-blanket method target.
18271830 */
18281831 pragma [ nomagic]
1829- predicate hasNoCompatibleNonBlanketTargetMutBorrow ( string derefChain ) {
1832+ predicate hasNoCompatibleNonBlanketTargetMutBorrow ( DerefChain derefChain ) {
18301833 exists ( Type strippedType |
18311834 this .hasNoCompatibleNonBlanketTargetMutBorrowToIndex ( derefChain , _, strippedType ,
18321835 getLastLookupTypeIndex ( strippedType ) )
@@ -1846,7 +1849,7 @@ private module MethodResolution {
18461849 * [1]: https://doc.rust-lang.org/reference/expressions/method-call-expr.html#r-expr.method.candidate-receivers
18471850 */
18481851 pragma [ nomagic]
1849- Type getACandidateReceiverTypeAt ( string derefChain , BorrowKind borrow , TypePath path ) {
1852+ Type getACandidateReceiverTypeAt ( DerefChain derefChain , BorrowKind borrow , TypePath path ) {
18501853 result = this .getACandidateReceiverTypeAtNoBorrow ( derefChain , path ) and
18511854 borrow = TNoBorrowKind ( )
18521855 or
@@ -1879,23 +1882,23 @@ private module MethodResolution {
18791882 * `derefChain` and the enum `borrow`.
18801883 */
18811884 pragma [ nomagic]
1882- Method resolveCallTarget ( ImplOrTraitItemNode i , string derefChain , BorrowKind borrow ) {
1885+ Method resolveCallTarget ( ImplOrTraitItemNode i , DerefChain derefChain , BorrowKind borrow ) {
18831886 exists ( MethodCallCand mcc |
18841887 mcc = MkMethodCallCand ( this , derefChain , borrow ) and
18851888 result = mcc .resolveCallTarget ( i )
18861889 )
18871890 }
18881891
18891892 predicate receiverHasImplicitDeref ( AstNode receiver ) {
1890- exists ( ImplicitDeref :: DerefImplItemNode impl |
1893+ exists ( DerefImplItemNode impl |
18911894 impl .isRefImpl ( ) and
1892- exists ( this .resolveCallTarget ( _, "." + impl . getId ( ) , TNoBorrowKind ( ) ) ) and
1895+ exists ( this .resolveCallTarget ( _, DerefChain :: singleton ( impl ) , TNoBorrowKind ( ) ) ) and
18931896 receiver = this .getArg ( any ( ArgumentPosition pos | pos .isSelf ( ) ) )
18941897 )
18951898 }
18961899
18971900 predicate argumentHasImplicitBorrow ( AstNode arg , BorrowKind borrow ) {
1898- exists ( this .resolveCallTarget ( _, "" , borrow ) ) and
1901+ exists ( this .resolveCallTarget ( _, DerefChain :: nil ( ) , borrow ) ) and
18991902 borrow != TNoBorrowKind ( ) and
19001903 arg = this .getArg ( any ( ArgumentPosition pos | pos .isSelf ( ) ) )
19011904 }
@@ -2056,14 +2059,14 @@ private module MethodResolution {
20562059 }
20572060
20582061 private newtype TMethodCallCand =
2059- MkMethodCallCand ( MethodCall mc , string derefChain , BorrowKind borrow ) {
2062+ MkMethodCallCand ( MethodCall mc , DerefChain derefChain , BorrowKind borrow ) {
20602063 exists ( mc .getACandidateReceiverTypeAt ( derefChain , borrow , _) )
20612064 }
20622065
20632066 /** A method call with a dereference chain and a potential borrow. */
20642067 private class MethodCallCand extends MkMethodCallCand {
20652068 MethodCall mc_ ;
2066- string derefChain ;
2069+ DerefChain derefChain ;
20672070 BorrowKind borrow ;
20682071
20692072 MethodCallCand ( ) { this = MkMethodCallCand ( mc_ , derefChain , borrow ) }
@@ -2161,51 +2164,16 @@ private module MethodResolution {
21612164 }
21622165
21632166 module ImplicitDeref {
2164- private import codeql.rust.elements.internal.generated.Raw
2165- private import codeql.rust.elements.internal.generated.Synth
2166-
2167- /** An `impl` block that implements the `Deref` trait. */
2168- class DerefImplItemNode extends ImplItemNode {
2169- DerefImplItemNode ( ) { this .resolveTraitTy ( ) instanceof DerefTrait }
2170-
2171- /**
2172- * Holds if this `impl` block is the special `Deref` implementation for
2173- * `&T` or `&mut T`:
2174- *
2175- * ```rust
2176- * impl<T: ?Sized> const Deref for &T
2177- * ```
2178- *
2179- * or
2180- *
2181- * ```rust
2182- * impl<T: ?Sized> const Deref for &mut T
2183- * ```
2184- */
2185- predicate isRefImpl ( ) { this .resolveSelfTyBuiltin ( ) instanceof Builtins:: RefType }
2186-
2187- /** Gets an internal unique ID used to identify this block amongst all `Deref` impl blocks. */
2188- int getId ( ) { idOfRaw ( Synth:: convertAstNodeToRaw ( this ) , result ) }
2189- }
2190-
2191- private class DerefImplItemRaw extends Raw:: Impl {
2192- DerefImplItemRaw ( ) { this = Synth:: convertAstNodeToRaw ( any ( DerefImplItemNode i ) ) }
2193- }
2194-
2195- private predicate id ( DerefImplItemRaw x , DerefImplItemRaw y ) { x = y }
2196-
2197- private predicate idOfRaw ( DerefImplItemRaw x , int y ) = equivalenceRelation( id / 2 ) ( x , y )
2198-
21992167 private newtype TMethodCallDerefCand =
2200- MkMethodCallDerefCand ( MethodCall mc , string derefChain ) {
2168+ MkMethodCallDerefCand ( MethodCall mc , DerefChain derefChain ) {
22012169 mc .supportsAutoDerefAndBorrow ( ) and
22022170 mc .hasNoCompatibleTargetMutBorrow ( derefChain ) and
22032171 exists ( mc .getACandidateReceiverTypeAtNoBorrow ( derefChain , _) )
22042172 }
22052173
22062174 private class MethodCallDerefCand extends MkMethodCallDerefCand {
22072175 MethodCall mc_ ;
2208- string derefChain ;
2176+ DerefChain derefChain ;
22092177
22102178 MethodCallDerefCand ( ) { this = MkMethodCallDerefCand ( mc_ , derefChain ) }
22112179
@@ -2241,7 +2209,7 @@ private module MethodResolution {
22412209
22422210 pragma [ nomagic]
22432211 Type getDereferencedCandidateReceiverType (
2244- MethodCall mc , DerefImplItemNode impl , string derefChain , TypePath path
2212+ MethodCall mc , DerefImplItemNode impl , DerefChain derefChain , TypePath path
22452213 ) {
22462214 exists ( MethodCallDerefCand mcc , TypePath exprPath |
22472215 mcc = MkMethodCallDerefCand ( mc , derefChain ) and
@@ -2607,10 +2575,10 @@ private Type inferMethodCallType1(AstNode n, boolean isReturn, TypePath path) {
26072575 path = path0
26082576 or
26092577 // adjust for implicit deref
2610- exists ( MethodResolution :: ImplicitDeref :: DerefImplItemNode impl |
2578+ exists ( DerefImplItemNode impl |
26112579 impl .isRefImpl ( ) and
26122580 apos .isSelf ( ) and
2613- derefChainBorrow = "." + impl . getId ( ) + ";" and
2581+ derefChainBorrow = DerefChain :: singleton ( impl ) + ";" and
26142582 path = TypePath:: cons ( getRefTypeParameter ( ) , path0 )
26152583 )
26162584 or
0 commit comments