@@ -1441,24 +1441,13 @@ private module MethodResolution {
14411441 * Same as `getACandidateReceiverTypeAt`, but without borrows.
14421442 */
14431443 pragma [ nomagic]
1444- private Type getACandidateReceiverTypeAtNoBorrow ( string derefChain , TypePath path ) {
1444+ Type getACandidateReceiverTypeAtNoBorrow ( string derefChain , TypePath path ) {
14451445 result = this .getReceiverTypeAt ( path ) and
14461446 derefChain = ""
14471447 or
1448- this .supportsAutoDerefAndBorrow ( ) and
1449- exists ( TypePath path0 , Type t0 , string derefChain0 |
1450- this .hasNoCompatibleTargetMutBorrow ( derefChain0 ) and
1451- t0 = this .getACandidateReceiverTypeAtNoBorrow ( derefChain0 , path0 )
1452- |
1453- path0 .isCons ( getRefTypeParameter ( ) , path ) and
1454- result = t0 and
1455- derefChain = derefChain0 + ".ref"
1456- or
1457- path0 .isEmpty ( ) and
1458- path = path0 and
1459- t0 = getStringStruct ( ) and
1460- result = getStrStruct ( ) and
1461- derefChain = derefChain0 + ".str"
1448+ exists ( ImplicitDeref:: DerefImplItemNode impl , string derefChain0 |
1449+ result = ImplicitDeref:: getDereferencedCandidateReceiverType ( this , impl , derefChain0 , path ) and
1450+ derefChain = derefChain0 + "." + impl .getId ( )
14621451 )
14631452 }
14641453
@@ -1698,8 +1687,11 @@ private module MethodResolution {
16981687 }
16991688
17001689 predicate receiverHasImplicitDeref ( AstNode receiver ) {
1701- exists ( this .resolveCallTarget ( _, ".ref" , TNoBorrowKind ( ) ) ) and
1702- receiver = this .getArg ( any ( ArgumentPosition pos | pos .isSelf ( ) ) )
1690+ exists ( ImplicitDeref:: DerefImplItemNode impl |
1691+ impl .isRefImpl ( ) and
1692+ exists ( this .resolveCallTarget ( _, "." + impl .getId ( ) , TNoBorrowKind ( ) ) ) and
1693+ receiver = this .getArg ( any ( ArgumentPosition pos | pos .isSelf ( ) ) )
1694+ )
17031695 }
17041696
17051697 predicate argumentHasImplicitBorrow ( AstNode arg , BorrowKind borrow ) {
@@ -1969,6 +1961,98 @@ private module MethodResolution {
19691961 Location getLocation ( ) { result = mc_ .getLocation ( ) }
19701962 }
19711963
1964+ module ImplicitDeref {
1965+ private import codeql.rust.elements.internal.generated.Raw
1966+ private import codeql.rust.elements.internal.generated.Synth
1967+
1968+ /** An `impl` block that implements the `Deref` trait. */
1969+ class DerefImplItemNode extends ImplItemNode {
1970+ DerefImplItemNode ( ) { this .resolveTraitTy ( ) instanceof DerefTrait }
1971+
1972+ /**
1973+ * Holds if this `impl` block is the special `Deref` implementation for
1974+ * `&T` or `&mut T`:
1975+ *
1976+ * ```rust
1977+ * impl<T: ?Sized> const Deref for &T
1978+ * ```
1979+ *
1980+ * or
1981+ *
1982+ * ```rust
1983+ * impl<T: ?Sized> const Deref for &mut T
1984+ * ```
1985+ */
1986+ predicate isRefImpl ( ) { this .resolveSelfTyBuiltin ( ) instanceof Builtins:: RefType }
1987+
1988+ /** Gets an internal unique ID used to identify this block amongst all `Deref` impl blocks. */
1989+ int getId ( ) { idOfRaw ( Synth:: convertAstNodeToRaw ( this ) , result ) }
1990+ }
1991+
1992+ private class DerefImplItemRaw extends Raw:: Impl {
1993+ DerefImplItemRaw ( ) { this = Synth:: convertAstNodeToRaw ( any ( DerefImplItemNode i ) ) }
1994+ }
1995+
1996+ private predicate id ( DerefImplItemRaw x , DerefImplItemRaw y ) { x = y }
1997+
1998+ private predicate idOfRaw ( DerefImplItemRaw x , int y ) = equivalenceRelation( id / 2 ) ( x , y )
1999+
2000+ private newtype TMethodCallDerefCand =
2001+ MkMethodCallDerefCand ( MethodCall mc , string derefChain ) {
2002+ mc .supportsAutoDerefAndBorrow ( ) and
2003+ mc .hasNoCompatibleTargetMutBorrow ( derefChain ) and
2004+ exists ( mc .getACandidateReceiverTypeAtNoBorrow ( derefChain , _) )
2005+ }
2006+
2007+ private class MethodCallDerefCand extends MkMethodCallDerefCand {
2008+ MethodCall mc_ ;
2009+ string derefChain ;
2010+
2011+ MethodCallDerefCand ( ) { this = MkMethodCallDerefCand ( mc_ , derefChain ) }
2012+
2013+ MethodCall getMethodCall ( ) { result = mc_ }
2014+
2015+ Type getTypeAt ( TypePath path ) {
2016+ result = substituteLookupTraits ( mc_ .getACandidateReceiverTypeAtNoBorrow ( derefChain , path ) ) and
2017+ not result = TNeverType ( ) and
2018+ not result = TUnknownType ( )
2019+ }
2020+
2021+ string toString ( ) { result = mc_ .toString ( ) + " [" + derefChain + "]" }
2022+
2023+ Location getLocation ( ) { result = mc_ .getLocation ( ) }
2024+ }
2025+
2026+ private module MethodCallSatisfiesConstraintInput implements
2027+ SatisfiesConstraintInputSig< MethodCallDerefCand >
2028+ {
2029+ pragma [ nomagic]
2030+ predicate relevantConstraint ( MethodCallDerefCand mc , Type constraint ) {
2031+ exists ( mc ) and
2032+ constraint .( TraitType ) .getTrait ( ) instanceof DerefTrait
2033+ }
2034+
2035+ predicate useUniversalConditions ( ) { none ( ) }
2036+ }
2037+
2038+ pragma [ nomagic]
2039+ private AssociatedTypeTypeParameter getDerefTargetTypeParameter ( ) {
2040+ result .getTypeAlias ( ) = any ( DerefTrait ft ) .getTargetType ( )
2041+ }
2042+
2043+ pragma [ nomagic]
2044+ Type getDereferencedCandidateReceiverType (
2045+ MethodCall mc , DerefImplItemNode impl , string derefChain , TypePath path
2046+ ) {
2047+ exists ( MethodCallDerefCand mcc , TypePath exprPath |
2048+ mcc = MkMethodCallDerefCand ( mc , derefChain ) and
2049+ SatisfiesConstraint< MethodCallDerefCand , MethodCallSatisfiesConstraintInput > :: satisfiesConstraintType ( mcc ,
2050+ impl , _, exprPath , result ) and
2051+ exprPath .isCons ( getDerefTargetTypeParameter ( ) , path )
2052+ )
2053+ }
2054+ }
2055+
19722056 private module ReceiverSatisfiesBlanketLikeConstraintInput implements
19732057 BlanketImplementation:: SatisfiesBlanketConstraintInputSig< MethodCallCand >
19742058 {
@@ -2347,9 +2431,12 @@ private Type inferMethodCallType1(AstNode n, boolean isReturn, TypePath path) {
23472431 path = path0
23482432 or
23492433 // adjust for implicit deref
2350- apos .isSelf ( ) and
2351- derefChainBorrow = ".ref;" and
2352- path = TypePath:: cons ( getRefTypeParameter ( ) , path0 )
2434+ exists ( MethodResolution:: ImplicitDeref:: DerefImplItemNode impl |
2435+ impl .isRefImpl ( ) and
2436+ apos .isSelf ( ) and
2437+ derefChainBorrow = "." + impl .getId ( ) + ";" and
2438+ path = TypePath:: cons ( getRefTypeParameter ( ) , path0 )
2439+ )
23532440 or
23542441 // adjust for implicit borrow
23552442 apos .isSelf ( ) and
@@ -3156,9 +3243,6 @@ private Type inferTryExprType(TryExpr te, TypePath path) {
31563243pragma [ nomagic]
31573244private StructType getStrStruct ( ) { result = TStruct ( any ( Builtins:: Str s ) ) }
31583245
3159- pragma [ nomagic]
3160- private StructType getStringStruct ( ) { result = TStruct ( any ( StringStruct s ) ) }
3161-
31623246pragma [ nomagic]
31633247private Type inferLiteralType ( LiteralExpr le , TypePath path , boolean certain ) {
31643248 path .isEmpty ( ) and
0 commit comments