@@ -273,10 +273,6 @@ private predicate typeEquality(AstNode n1, TypePath prefix1, AstNode n2, TypePat
273
273
prefix1 .isEmpty ( ) and
274
274
prefix2 = TypePath:: singleton ( TRefTypeParameter ( ) )
275
275
or
276
- n1 = n2 .( DerefExpr ) .getExpr ( ) and
277
- prefix1 = TypePath:: singleton ( TRefTypeParameter ( ) ) and
278
- prefix2 .isEmpty ( )
279
- or
280
276
exists ( BlockExpr be |
281
277
n1 = be and
282
278
n2 = be .getStmtList ( ) .getTailExpr ( ) and
@@ -640,20 +636,20 @@ private module CallExprBaseMatchingInput implements MatchingInputSig {
640
636
}
641
637
642
638
private newtype TAccessPosition =
643
- TArgumentAccessPosition ( ArgumentPosition pos , Boolean borrowed ) or
639
+ TArgumentAccessPosition ( ArgumentPosition pos , Boolean borrowed , Boolean certain ) or
644
640
TReturnAccessPosition ( )
645
641
646
642
class AccessPosition extends TAccessPosition {
647
- ArgumentPosition getArgumentPosition ( ) { this = TArgumentAccessPosition ( result , _) }
643
+ ArgumentPosition getArgumentPosition ( ) { this = TArgumentAccessPosition ( result , _, _ ) }
648
644
649
- predicate isBorrowed ( ) { this = TArgumentAccessPosition ( _, true ) }
645
+ predicate isBorrowed ( boolean certain ) { this = TArgumentAccessPosition ( _, true , certain ) }
650
646
651
647
predicate isReturn ( ) { this = TReturnAccessPosition ( ) }
652
648
653
649
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
657
653
)
658
654
or
659
655
this .isReturn ( ) and
@@ -674,10 +670,15 @@ private module CallExprBaseMatchingInput implements MatchingInputSig {
674
670
}
675
671
676
672
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
+ )
681
682
)
682
683
or
683
684
result = this and apos .isReturn ( )
@@ -705,51 +706,54 @@ private module CallExprBaseMatchingInput implements MatchingInputSig {
705
706
predicate adjustAccessType (
706
707
AccessPosition apos , Declaration target , TypePath path , Type t , TypePath pathAdj , Type tAdj
707
708
) {
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 ( )
717
723
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 ( ) , _)
719
733
then
734
+ pathAdj = path and
735
+ tAdj = t
736
+ else (
720
737
// 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
726
740
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
748
751
)
749
- else (
750
- pathAdj = path and
751
- tAdj = t
752
752
)
753
+ or
754
+ not apos .isBorrowed ( _) and
755
+ pathAdj = path and
756
+ tAdj = t
753
757
}
754
758
}
755
759
@@ -766,35 +770,47 @@ private Type inferCallExprBaseType(AstNode n, TypePath path) {
766
770
TypePath path0
767
771
|
768
772
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
+ (
779
802
not path0 .isCons ( TRefTypeParameter ( ) , _) and
780
803
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 )
795
808
)
796
809
)
797
- else path = path0
810
+ )
811
+ or
812
+ not apos .isBorrowed ( _) and
813
+ path = path0
798
814
)
799
815
}
800
816
@@ -1387,7 +1403,7 @@ private module Cached {
1387
1403
predicate receiverHasImplicitDeref ( AstNode receiver ) {
1388
1404
exists ( CallExprBaseMatchingInput:: Access a , CallExprBaseMatchingInput:: AccessPosition apos |
1389
1405
apos .getArgumentPosition ( ) .isSelf ( ) and
1390
- apos .isBorrowed ( ) and
1406
+ apos .isBorrowed ( _ ) and
1391
1407
receiver = a .getNodeAt ( apos ) and
1392
1408
inferType ( receiver ) = TRefType ( ) and
1393
1409
CallExprBaseMatching:: inferAccessType ( a , apos , TypePath:: nil ( ) ) != TRefType ( )
@@ -1399,7 +1415,7 @@ private module Cached {
1399
1415
predicate receiverHasImplicitBorrow ( AstNode receiver ) {
1400
1416
exists ( CallExprBaseMatchingInput:: Access a , CallExprBaseMatchingInput:: AccessPosition apos |
1401
1417
apos .getArgumentPosition ( ) .isSelf ( ) and
1402
- apos .isBorrowed ( ) and
1418
+ apos .isBorrowed ( _ ) and
1403
1419
receiver = a .getNodeAt ( apos ) and
1404
1420
CallExprBaseMatching:: inferAccessType ( a , apos , TypePath:: nil ( ) ) = TRefType ( ) and
1405
1421
inferType ( receiver ) != TRefType ( )
0 commit comments