@@ -1553,24 +1553,13 @@ private module MethodResolution {
15531553 * Same as `getACandidateReceiverTypeAt`, but without borrows.
15541554 */
15551555 pragma [ nomagic]
1556- private Type getACandidateReceiverTypeAtNoBorrow ( string derefChain , TypePath path ) {
1556+ Type getACandidateReceiverTypeAtNoBorrow ( string derefChain , TypePath path ) {
15571557 result = this .getReceiverTypeAt ( path ) and
15581558 derefChain = ""
15591559 or
1560- this .supportsAutoDerefAndBorrow ( ) and
1561- exists ( TypePath path0 , Type t0 , string derefChain0 |
1562- this .hasNoCompatibleTargetMutBorrow ( derefChain0 ) and
1563- t0 = this .getACandidateReceiverTypeAtNoBorrow ( derefChain0 , path0 )
1564- |
1565- path0 .isCons ( getRefTypeParameter ( ) , path ) and
1566- result = t0 and
1567- derefChain = derefChain0 + ".ref"
1568- or
1569- path0 .isEmpty ( ) and
1570- path = path0 and
1571- t0 = getStringStruct ( ) and
1572- result = getStrStruct ( ) and
1573- derefChain = derefChain0 + ".str"
1560+ exists ( ImplicitDeref:: DerefImplItemNode impl , string derefChain0 |
1561+ result = ImplicitDeref:: getDereferencedCandidateReceiverType ( this , impl , derefChain0 , path ) and
1562+ derefChain = derefChain0 + "." + impl .getId ( )
15741563 )
15751564 }
15761565
@@ -1818,8 +1807,11 @@ private module MethodResolution {
18181807 }
18191808
18201809 predicate receiverHasImplicitDeref ( AstNode receiver ) {
1821- exists ( this .resolveCallTarget ( _, ".ref" , TNoBorrowKind ( ) ) ) and
1822- receiver = this .getArg ( any ( ArgumentPosition pos | pos .isSelf ( ) ) )
1810+ exists ( ImplicitDeref:: DerefImplItemNode impl |
1811+ impl .isRefImpl ( ) and
1812+ exists ( this .resolveCallTarget ( _, "." + impl .getId ( ) , TNoBorrowKind ( ) ) ) and
1813+ receiver = this .getArg ( any ( ArgumentPosition pos | pos .isSelf ( ) ) )
1814+ )
18231815 }
18241816
18251817 predicate argumentHasImplicitBorrow ( AstNode arg , BorrowKind borrow ) {
@@ -2089,6 +2081,98 @@ private module MethodResolution {
20892081 Location getLocation ( ) { result = mc_ .getLocation ( ) }
20902082 }
20912083
2084+ module ImplicitDeref {
2085+ private import codeql.rust.elements.internal.generated.Raw
2086+ private import codeql.rust.elements.internal.generated.Synth
2087+
2088+ /** An `impl` block that implements the `Deref` trait. */
2089+ class DerefImplItemNode extends ImplItemNode {
2090+ DerefImplItemNode ( ) { this .resolveTraitTy ( ) instanceof DerefTrait }
2091+
2092+ /**
2093+ * Holds if this `impl` block is the special `Deref` implementation for
2094+ * `&T` or `&mut T`:
2095+ *
2096+ * ```rust
2097+ * impl<T: ?Sized> const Deref for &T
2098+ * ```
2099+ *
2100+ * or
2101+ *
2102+ * ```rust
2103+ * impl<T: ?Sized> const Deref for &mut T
2104+ * ```
2105+ */
2106+ predicate isRefImpl ( ) { this .resolveSelfTyBuiltin ( ) instanceof Builtins:: RefType }
2107+
2108+ /** Gets an internal unique ID used to identify this block amongst all `Deref` impl blocks. */
2109+ int getId ( ) { idOfRaw ( Synth:: convertAstNodeToRaw ( this ) , result ) }
2110+ }
2111+
2112+ private class DerefImplItemRaw extends Raw:: Impl {
2113+ DerefImplItemRaw ( ) { this = Synth:: convertAstNodeToRaw ( any ( DerefImplItemNode i ) ) }
2114+ }
2115+
2116+ private predicate id ( DerefImplItemRaw x , DerefImplItemRaw y ) { x = y }
2117+
2118+ private predicate idOfRaw ( DerefImplItemRaw x , int y ) = equivalenceRelation( id / 2 ) ( x , y )
2119+
2120+ private newtype TMethodCallDerefCand =
2121+ MkMethodCallDerefCand ( MethodCall mc , string derefChain ) {
2122+ mc .supportsAutoDerefAndBorrow ( ) and
2123+ mc .hasNoCompatibleTargetMutBorrow ( derefChain ) and
2124+ exists ( mc .getACandidateReceiverTypeAtNoBorrow ( derefChain , _) )
2125+ }
2126+
2127+ private class MethodCallDerefCand extends MkMethodCallDerefCand {
2128+ MethodCall mc_ ;
2129+ string derefChain ;
2130+
2131+ MethodCallDerefCand ( ) { this = MkMethodCallDerefCand ( mc_ , derefChain ) }
2132+
2133+ MethodCall getMethodCall ( ) { result = mc_ }
2134+
2135+ Type getTypeAt ( TypePath path ) {
2136+ result = substituteLookupTraits ( mc_ .getACandidateReceiverTypeAtNoBorrow ( derefChain , path ) ) and
2137+ not result = TNeverType ( ) and
2138+ not result = TUnknownType ( )
2139+ }
2140+
2141+ string toString ( ) { result = mc_ .toString ( ) + " [" + derefChain + "]" }
2142+
2143+ Location getLocation ( ) { result = mc_ .getLocation ( ) }
2144+ }
2145+
2146+ private module MethodCallSatisfiesConstraintInput implements
2147+ SatisfiesConstraintInputSig< MethodCallDerefCand >
2148+ {
2149+ pragma [ nomagic]
2150+ predicate relevantConstraint ( MethodCallDerefCand mc , Type constraint ) {
2151+ exists ( mc ) and
2152+ constraint .( TraitType ) .getTrait ( ) instanceof DerefTrait
2153+ }
2154+
2155+ predicate useUniversalConditions ( ) { none ( ) }
2156+ }
2157+
2158+ pragma [ nomagic]
2159+ private AssociatedTypeTypeParameter getDerefTargetTypeParameter ( ) {
2160+ result .getTypeAlias ( ) = any ( DerefTrait ft ) .getTargetType ( )
2161+ }
2162+
2163+ pragma [ nomagic]
2164+ Type getDereferencedCandidateReceiverType (
2165+ MethodCall mc , DerefImplItemNode impl , string derefChain , TypePath path
2166+ ) {
2167+ exists ( MethodCallDerefCand mcc , TypePath exprPath |
2168+ mcc = MkMethodCallDerefCand ( mc , derefChain ) and
2169+ SatisfiesConstraint< MethodCallDerefCand , MethodCallSatisfiesConstraintInput > :: satisfiesConstraintType ( mcc ,
2170+ impl , _, exprPath , result ) and
2171+ exprPath .isCons ( getDerefTargetTypeParameter ( ) , path )
2172+ )
2173+ }
2174+ }
2175+
20922176 private module ReceiverSatisfiesBlanketLikeConstraintInput implements
20932177 BlanketImplementation:: SatisfiesBlanketConstraintInputSig< MethodCallCand >
20942178 {
@@ -2444,9 +2528,12 @@ private Type inferMethodCallType1(AstNode n, boolean isReturn, TypePath path) {
24442528 path = path0
24452529 or
24462530 // adjust for implicit deref
2447- apos .isSelf ( ) and
2448- derefChainBorrow = ".ref;" and
2449- path = TypePath:: cons ( getRefTypeParameter ( ) , path0 )
2531+ exists ( MethodResolution:: ImplicitDeref:: DerefImplItemNode impl |
2532+ impl .isRefImpl ( ) and
2533+ apos .isSelf ( ) and
2534+ derefChainBorrow = "." + impl .getId ( ) + ";" and
2535+ path = TypePath:: cons ( getRefTypeParameter ( ) , path0 )
2536+ )
24502537 or
24512538 // adjust for implicit borrow
24522539 apos .isSelf ( ) and
@@ -3292,9 +3379,6 @@ private Type inferTryExprType(TryExpr te, TypePath path) {
32923379pragma [ nomagic]
32933380private StructType getStrStruct ( ) { result = TStruct ( any ( Builtins:: Str s ) ) }
32943381
3295- pragma [ nomagic]
3296- private StructType getStringStruct ( ) { result = TStruct ( any ( StringStruct s ) ) }
3297-
32983382pragma [ nomagic]
32993383private Type inferLiteralType ( LiteralExpr le , TypePath path , boolean certain ) {
33003384 path .isEmpty ( ) and
0 commit comments