@@ -1550,24 +1550,13 @@ private module MethodResolution {
15501550 * Same as `getACandidateReceiverTypeAt`, but without borrows.
15511551 */
15521552 pragma [ nomagic]
1553- private Type getACandidateReceiverTypeAtNoBorrow ( string derefChain , TypePath path ) {
1553+ Type getACandidateReceiverTypeAtNoBorrow ( string derefChain , TypePath path ) {
15541554 result = this .getReceiverTypeAt ( path ) and
15551555 derefChain = ""
15561556 or
1557- this .supportsAutoDerefAndBorrow ( ) and
1558- exists ( TypePath path0 , Type t0 , string derefChain0 |
1559- this .hasNoCompatibleTargetMutBorrow ( derefChain0 ) and
1560- t0 = this .getACandidateReceiverTypeAtNoBorrow ( derefChain0 , path0 )
1561- |
1562- path0 .isCons ( getRefTypeParameter ( ) , path ) and
1563- result = t0 and
1564- derefChain = derefChain0 + ".ref"
1565- or
1566- path0 .isEmpty ( ) and
1567- path = path0 and
1568- t0 = getStringStruct ( ) and
1569- result = getStrStruct ( ) and
1570- derefChain = derefChain0 + ".str"
1557+ exists ( ImplicitDeref:: DerefImplItemNode impl , string derefChain0 |
1558+ result = ImplicitDeref:: getDereferencedCandidateReceiverType ( this , impl , derefChain0 , path ) and
1559+ derefChain = derefChain0 + "." + impl .getId ( )
15711560 )
15721561 }
15731562
@@ -1895,8 +1884,11 @@ private module MethodResolution {
18951884 }
18961885
18971886 predicate receiverHasImplicitDeref ( AstNode receiver ) {
1898- exists ( this .resolveCallTarget ( _, ".ref" , TNoBorrowKind ( ) ) ) and
1899- receiver = this .getArg ( any ( ArgumentPosition pos | pos .isSelf ( ) ) )
1887+ exists ( ImplicitDeref:: DerefImplItemNode impl |
1888+ impl .isRefImpl ( ) and
1889+ exists ( this .resolveCallTarget ( _, "." + impl .getId ( ) , TNoBorrowKind ( ) ) ) and
1890+ receiver = this .getArg ( any ( ArgumentPosition pos | pos .isSelf ( ) ) )
1891+ )
19001892 }
19011893
19021894 predicate argumentHasImplicitBorrow ( AstNode arg , BorrowKind borrow ) {
@@ -2165,6 +2157,98 @@ private module MethodResolution {
21652157 Location getLocation ( ) { result = mc_ .getLocation ( ) }
21662158 }
21672159
2160+ module ImplicitDeref {
2161+ private import codeql.rust.elements.internal.generated.Raw
2162+ private import codeql.rust.elements.internal.generated.Synth
2163+
2164+ /** An `impl` block that implements the `Deref` trait. */
2165+ class DerefImplItemNode extends ImplItemNode {
2166+ DerefImplItemNode ( ) { this .resolveTraitTy ( ) instanceof DerefTrait }
2167+
2168+ /**
2169+ * Holds if this `impl` block is the special `Deref` implementation for
2170+ * `&T` or `&mut T`:
2171+ *
2172+ * ```rust
2173+ * impl<T: ?Sized> const Deref for &T
2174+ * ```
2175+ *
2176+ * or
2177+ *
2178+ * ```rust
2179+ * impl<T: ?Sized> const Deref for &mut T
2180+ * ```
2181+ */
2182+ predicate isRefImpl ( ) { this .resolveSelfTyBuiltin ( ) instanceof Builtins:: RefType }
2183+
2184+ /** Gets an internal unique ID used to identify this block amongst all `Deref` impl blocks. */
2185+ int getId ( ) { idOfRaw ( Synth:: convertAstNodeToRaw ( this ) , result ) }
2186+ }
2187+
2188+ private class DerefImplItemRaw extends Raw:: Impl {
2189+ DerefImplItemRaw ( ) { this = Synth:: convertAstNodeToRaw ( any ( DerefImplItemNode i ) ) }
2190+ }
2191+
2192+ private predicate id ( DerefImplItemRaw x , DerefImplItemRaw y ) { x = y }
2193+
2194+ private predicate idOfRaw ( DerefImplItemRaw x , int y ) = equivalenceRelation( id / 2 ) ( x , y )
2195+
2196+ private newtype TMethodCallDerefCand =
2197+ MkMethodCallDerefCand ( MethodCall mc , string derefChain ) {
2198+ mc .supportsAutoDerefAndBorrow ( ) and
2199+ mc .hasNoCompatibleTargetMutBorrow ( derefChain ) and
2200+ exists ( mc .getACandidateReceiverTypeAtNoBorrow ( derefChain , _) )
2201+ }
2202+
2203+ private class MethodCallDerefCand extends MkMethodCallDerefCand {
2204+ MethodCall mc_ ;
2205+ string derefChain ;
2206+
2207+ MethodCallDerefCand ( ) { this = MkMethodCallDerefCand ( mc_ , derefChain ) }
2208+
2209+ MethodCall getMethodCall ( ) { result = mc_ }
2210+
2211+ Type getTypeAt ( TypePath path ) {
2212+ result = substituteLookupTraits ( mc_ .getACandidateReceiverTypeAtNoBorrow ( derefChain , path ) ) and
2213+ not result = TNeverType ( ) and
2214+ not result = TUnknownType ( )
2215+ }
2216+
2217+ string toString ( ) { result = mc_ .toString ( ) + " [" + derefChain + "]" }
2218+
2219+ Location getLocation ( ) { result = mc_ .getLocation ( ) }
2220+ }
2221+
2222+ private module MethodCallSatisfiesConstraintInput implements
2223+ SatisfiesConstraintInputSig< MethodCallDerefCand >
2224+ {
2225+ pragma [ nomagic]
2226+ predicate relevantConstraint ( MethodCallDerefCand mc , Type constraint ) {
2227+ exists ( mc ) and
2228+ constraint .( TraitType ) .getTrait ( ) instanceof DerefTrait
2229+ }
2230+
2231+ predicate useUniversalConditions ( ) { none ( ) }
2232+ }
2233+
2234+ pragma [ nomagic]
2235+ private AssociatedTypeTypeParameter getDerefTargetTypeParameter ( ) {
2236+ result .getTypeAlias ( ) = any ( DerefTrait ft ) .getTargetType ( )
2237+ }
2238+
2239+ pragma [ nomagic]
2240+ Type getDereferencedCandidateReceiverType (
2241+ MethodCall mc , DerefImplItemNode impl , string derefChain , TypePath path
2242+ ) {
2243+ exists ( MethodCallDerefCand mcc , TypePath exprPath |
2244+ mcc = MkMethodCallDerefCand ( mc , derefChain ) and
2245+ SatisfiesConstraint< MethodCallDerefCand , MethodCallSatisfiesConstraintInput > :: satisfiesConstraintType ( mcc ,
2246+ impl , _, exprPath , result ) and
2247+ exprPath .isCons ( getDerefTargetTypeParameter ( ) , path )
2248+ )
2249+ }
2250+ }
2251+
21682252 private module ReceiverSatisfiesBlanketLikeConstraintInput implements
21692253 BlanketImplementation:: SatisfiesBlanketConstraintInputSig< MethodCallCand >
21702254 {
@@ -2522,9 +2606,12 @@ private Type inferMethodCallType1(AstNode n, boolean isReturn, TypePath path) {
25222606 path = path0
25232607 or
25242608 // adjust for implicit deref
2525- apos .isSelf ( ) and
2526- derefChainBorrow = ".ref;" and
2527- path = TypePath:: cons ( getRefTypeParameter ( ) , path0 )
2609+ exists ( MethodResolution:: ImplicitDeref:: DerefImplItemNode impl |
2610+ impl .isRefImpl ( ) and
2611+ apos .isSelf ( ) and
2612+ derefChainBorrow = "." + impl .getId ( ) + ";" and
2613+ path = TypePath:: cons ( getRefTypeParameter ( ) , path0 )
2614+ )
25282615 or
25292616 // adjust for implicit borrow
25302617 apos .isSelf ( ) and
@@ -3372,9 +3459,6 @@ private Type inferTryExprType(TryExpr te, TypePath path) {
33723459pragma [ nomagic]
33733460private StructType getStrStruct ( ) { result = TStruct ( any ( Builtins:: Str s ) ) }
33743461
3375- pragma [ nomagic]
3376- private StructType getStringStruct ( ) { result = TStruct ( any ( StringStruct s ) ) }
3377-
33783462pragma [ nomagic]
33793463private Type inferLiteralType ( LiteralExpr le , TypePath path , boolean certain ) {
33803464 path .isEmpty ( ) and
0 commit comments