@@ -273,10 +273,6 @@ private predicate typeEquality(AstNode n1, TypePath prefix1, AstNode n2, TypePat
273273 prefix1 .isEmpty ( ) and
274274 prefix2 = TypePath:: singleton ( TRefTypeParameter ( ) )
275275 or
276- n1 = n2 .( DerefExpr ) .getExpr ( ) and
277- prefix1 = TypePath:: singleton ( TRefTypeParameter ( ) ) and
278- prefix2 .isEmpty ( )
279- or
280276 exists ( BlockExpr be |
281277 n1 = be and
282278 n2 = be .getStmtList ( ) .getTailExpr ( ) and
@@ -640,20 +636,20 @@ private module CallExprBaseMatchingInput implements MatchingInputSig {
640636 }
641637
642638 private newtype TAccessPosition =
643- TArgumentAccessPosition ( ArgumentPosition pos , Boolean borrowed ) or
639+ TArgumentAccessPosition ( ArgumentPosition pos , Boolean borrowed , Boolean certain ) or
644640 TReturnAccessPosition ( )
645641
646642 class AccessPosition extends TAccessPosition {
647- ArgumentPosition getArgumentPosition ( ) { this = TArgumentAccessPosition ( result , _) }
643+ ArgumentPosition getArgumentPosition ( ) { this = TArgumentAccessPosition ( result , _, _ ) }
648644
649- predicate isBorrowed ( ) { this = TArgumentAccessPosition ( _, true ) }
645+ predicate isBorrowed ( boolean certain ) { this = TArgumentAccessPosition ( _, true , certain ) }
650646
651647 predicate isReturn ( ) { this = TReturnAccessPosition ( ) }
652648
653649 string toString ( ) {
654- exists ( ArgumentPosition pos , boolean borrowed |
655- this = TArgumentAccessPosition ( pos , borrowed ) and
656- result = pos + ":" + borrowed
650+ exists ( ArgumentPosition pos , boolean borrowed , boolean certain |
651+ this = TArgumentAccessPosition ( pos , borrowed , certain ) and
652+ result = pos + ":" + borrowed + ":" + certain
657653 )
658654 or
659655 this .isReturn ( ) and
@@ -674,10 +670,15 @@ private module CallExprBaseMatchingInput implements MatchingInputSig {
674670 }
675671
676672 AstNode getNodeAt ( AccessPosition apos ) {
677- exists ( ArgumentPosition pos , boolean borrowed |
678- apos = TArgumentAccessPosition ( pos , borrowed ) and
679- result = this .getArgument ( pos ) and
680- if this .implicitBorrowAt ( pos ) then borrowed = true else borrowed = false
673+ exists ( ArgumentPosition pos , boolean borrowed , boolean certain |
674+ apos = TArgumentAccessPosition ( pos , borrowed , certain ) and
675+ result = this .getArgument ( pos )
676+ |
677+ if this .implicitBorrowAt ( pos , _)
678+ then borrowed = true and this .implicitBorrowAt ( pos , certain )
679+ else (
680+ borrowed = false and certain = true
681+ )
681682 )
682683 or
683684 result = this and apos .isReturn ( )
@@ -705,51 +706,54 @@ private module CallExprBaseMatchingInput implements MatchingInputSig {
705706 predicate adjustAccessType (
706707 AccessPosition apos , Declaration target , TypePath path , Type t , TypePath pathAdj , Type tAdj
707708 ) {
708- if apos .isBorrowed ( )
709- then
710- exists ( Type selfParamType |
711- selfParamType =
712- target
713- .getParameterType ( TArgumentDeclarationPosition ( apos .getArgumentPosition ( ) ) ,
714- TypePath:: nil ( ) )
715- |
716- if selfParamType = TRefType ( )
709+ apos .isBorrowed ( true ) and
710+ pathAdj = TypePath:: cons ( TRefTypeParameter ( ) , path ) and
711+ tAdj = t
712+ or
713+ apos .isBorrowed ( false ) and
714+ exists ( Type selfParamType |
715+ selfParamType =
716+ target
717+ .getParameterType ( TArgumentDeclarationPosition ( apos .getArgumentPosition ( ) ) ,
718+ TypePath:: nil ( ) )
719+ |
720+ if selfParamType = TRefType ( )
721+ then
722+ if t != TRefType ( ) and path .isEmpty ( )
717723 then
718- if t != TRefType ( ) and path .isEmpty ( )
724+ // adjust for implicit borrow
725+ pathAdj .isEmpty ( ) and
726+ tAdj = TRefType ( )
727+ or
728+ // adjust for implicit borrow
729+ pathAdj = TypePath:: singleton ( TRefTypeParameter ( ) ) and
730+ tAdj = t
731+ else
732+ if path .isCons ( TRefTypeParameter ( ) , _)
719733 then
734+ pathAdj = path and
735+ tAdj = t
736+ else (
720737 // adjust for implicit borrow
721- pathAdj .isEmpty ( ) and
722- tAdj = TRefType ( )
723- or
724- // adjust for implicit borrow
725- pathAdj = TypePath:: singleton ( TRefTypeParameter ( ) ) and
738+ not ( t = TRefType ( ) and path .isEmpty ( ) ) and
739+ pathAdj = TypePath:: cons ( TRefTypeParameter ( ) , path ) and
726740 tAdj = t
727- else
728- if path .isCons ( TRefTypeParameter ( ) , _)
729- then
730- pathAdj = path and
731- tAdj = t
732- else (
733- // adjust for implicit borrow
734- not ( t = TRefType ( ) and path .isEmpty ( ) ) and
735- pathAdj = TypePath:: cons ( TRefTypeParameter ( ) , path ) and
736- tAdj = t
737- )
738- else (
739- // adjust for implicit deref
740- path .isCons ( TRefTypeParameter ( ) , pathAdj ) and
741- tAdj = t
742- or
743- not path .isCons ( TRefTypeParameter ( ) , _) and
744- not ( t = TRefType ( ) and path .isEmpty ( ) ) and
745- pathAdj = path and
746- tAdj = t
747- )
741+ )
742+ else (
743+ // adjust for implicit deref
744+ path .isCons ( TRefTypeParameter ( ) , pathAdj ) and
745+ tAdj = t
746+ or
747+ not path .isCons ( TRefTypeParameter ( ) , _) and
748+ not ( t = TRefType ( ) and path .isEmpty ( ) ) and
749+ pathAdj = path and
750+ tAdj = t
748751 )
749- else (
750- pathAdj = path and
751- tAdj = t
752752 )
753+ or
754+ not apos .isBorrowed ( _) and
755+ pathAdj = path and
756+ tAdj = t
753757 }
754758}
755759
@@ -766,35 +770,47 @@ private Type inferCallExprBaseType(AstNode n, TypePath path) {
766770 TypePath path0
767771 |
768772 n = a .getNodeAt ( apos ) and
769- result = CallExprBaseMatching:: inferAccessType ( a , apos , path0 ) and
770- if apos .isBorrowed ( )
771- then
772- exists ( Type argType | argType = inferType ( n ) |
773- if argType = TRefType ( )
774- then
775- path = path0 and
776- path0 .isCons ( TRefTypeParameter ( ) , _)
777- or
778- // adjust for implicit deref
773+ result = CallExprBaseMatching:: inferAccessType ( a , apos , path0 )
774+ |
775+ (
776+ apos .isBorrowed ( true )
777+ or
778+ // The desugaring of the unary `*e` is `*Deref::deref(&e)`. To handle the
779+ // deref expression after the call we must strip a `&` from the type at
780+ // the return position.
781+ apos .isReturn ( ) and a instanceof DerefExpr
782+ ) and
783+ path0 .isCons ( TRefTypeParameter ( ) , path )
784+ or
785+ apos .isBorrowed ( false ) and
786+ exists ( Type argType | argType = inferType ( n ) |
787+ if argType = TRefType ( )
788+ then
789+ path = path0 and
790+ path0 .isCons ( TRefTypeParameter ( ) , _)
791+ or
792+ // adjust for implicit deref
793+ not path0 .isCons ( TRefTypeParameter ( ) , _) and
794+ not ( path0 .isEmpty ( ) and result = TRefType ( ) ) and
795+ path = TypePath:: cons ( TRefTypeParameter ( ) , path0 )
796+ else (
797+ not (
798+ argType .( StructType ) .asItemNode ( ) instanceof StringStruct and
799+ result .( StructType ) .asItemNode ( ) instanceof Builtins:: Str
800+ ) and
801+ (
779802 not path0 .isCons ( TRefTypeParameter ( ) , _) and
780803 not ( path0 .isEmpty ( ) and result = TRefType ( ) ) and
781- path = TypePath:: cons ( TRefTypeParameter ( ) , path0 )
782- else (
783- not (
784- argType .( StructType ) .asItemNode ( ) instanceof StringStruct and
785- result .( StructType ) .asItemNode ( ) instanceof Builtins:: Str
786- ) and
787- (
788- not path0 .isCons ( TRefTypeParameter ( ) , _) and
789- not ( path0 .isEmpty ( ) and result = TRefType ( ) ) and
790- path = path0
791- or
792- // adjust for implicit borrow
793- path0 .isCons ( TRefTypeParameter ( ) , path )
794- )
804+ path = path0
805+ or
806+ // adjust for implicit borrow
807+ path0 .isCons ( TRefTypeParameter ( ) , path )
795808 )
796809 )
797- else path = path0
810+ )
811+ or
812+ not apos .isBorrowed ( _) and
813+ path = path0
798814 )
799815}
800816
@@ -1387,7 +1403,7 @@ private module Cached {
13871403 predicate receiverHasImplicitDeref ( AstNode receiver ) {
13881404 exists ( CallExprBaseMatchingInput:: Access a , CallExprBaseMatchingInput:: AccessPosition apos |
13891405 apos .getArgumentPosition ( ) .isSelf ( ) and
1390- apos .isBorrowed ( ) and
1406+ apos .isBorrowed ( _ ) and
13911407 receiver = a .getNodeAt ( apos ) and
13921408 inferType ( receiver ) = TRefType ( ) and
13931409 CallExprBaseMatching:: inferAccessType ( a , apos , TypePath:: nil ( ) ) != TRefType ( )
@@ -1399,7 +1415,7 @@ private module Cached {
13991415 predicate receiverHasImplicitBorrow ( AstNode receiver ) {
14001416 exists ( CallExprBaseMatchingInput:: Access a , CallExprBaseMatchingInput:: AccessPosition apos |
14011417 apos .getArgumentPosition ( ) .isSelf ( ) and
1402- apos .isBorrowed ( ) and
1418+ apos .isBorrowed ( _ ) and
14031419 receiver = a .getNodeAt ( apos ) and
14041420 CallExprBaseMatching:: inferAccessType ( a , apos , TypePath:: nil ( ) ) = TRefType ( ) and
14051421 inferType ( receiver ) != TRefType ( )
0 commit comments