@@ -8,6 +8,7 @@ private import TypeMention
88private import codeql.typeinference.internal.TypeInference
99private import codeql.rust.frameworks.stdlib.Stdlib
1010private import codeql.rust.frameworks.stdlib.Bultins as Builtins
11+ private import codeql.rust.elements.Call
1112
1213class Type = T:: Type ;
1314
@@ -459,28 +460,25 @@ private Type inferPathExprType(PathExpr pe, TypePath path) {
459460 * like `foo::bar(baz)` and `foo.bar(baz)`.
460461 */
461462private module CallExprBaseMatchingInput implements MatchingInputSig {
462- private predicate paramPos ( ParamList pl , Param p , int pos , boolean inMethod ) {
463- p = pl .getParam ( pos ) and
464- if pl .hasSelfParam ( ) then inMethod = true else inMethod = false
465- }
463+ private predicate paramPos ( ParamList pl , Param p , int pos ) { p = pl .getParam ( pos ) }
466464
467465 private newtype TDeclarationPosition =
468466 TSelfDeclarationPosition ( ) or
469- TPositionalDeclarationPosition ( int pos , boolean inMethod ) { paramPos ( _, _, pos , inMethod ) } or
467+ TPositionalDeclarationPosition ( int pos ) { paramPos ( _, _, pos ) } or
470468 TReturnDeclarationPosition ( )
471469
472470 class DeclarationPosition extends TDeclarationPosition {
473471 predicate isSelf ( ) { this = TSelfDeclarationPosition ( ) }
474472
475- int asPosition ( boolean inMethod ) { this = TPositionalDeclarationPosition ( result , inMethod ) }
473+ int asPosition ( ) { this = TPositionalDeclarationPosition ( result ) }
476474
477475 predicate isReturn ( ) { this = TReturnDeclarationPosition ( ) }
478476
479477 string toString ( ) {
480478 this .isSelf ( ) and
481479 result = "self"
482480 or
483- result = this .asPosition ( _ ) .toString ( )
481+ result = this .asPosition ( ) .toString ( )
484482 or
485483 this .isReturn ( ) and
486484 result = "(return)"
@@ -513,7 +511,7 @@ private module CallExprBaseMatchingInput implements MatchingInputSig {
513511 override Type getParameterType ( DeclarationPosition dpos , TypePath path ) {
514512 exists ( int pos |
515513 result = this .getTupleField ( pos ) .getTypeRepr ( ) .( TypeMention ) .resolveTypeAt ( path ) and
516- dpos = TPositionalDeclarationPosition ( pos , false )
514+ dpos = TPositionalDeclarationPosition ( pos )
517515 )
518516 }
519517
@@ -536,7 +534,7 @@ private module CallExprBaseMatchingInput implements MatchingInputSig {
536534 override Type getParameterType ( DeclarationPosition dpos , TypePath path ) {
537535 exists ( int p |
538536 result = this .getTupleField ( p ) .getTypeRepr ( ) .( TypeMention ) .resolveTypeAt ( path ) and
539- dpos = TPositionalDeclarationPosition ( p , false )
537+ dpos = TPositionalDeclarationPosition ( p )
540538 )
541539 }
542540
@@ -566,9 +564,9 @@ private module CallExprBaseMatchingInput implements MatchingInputSig {
566564 }
567565
568566 override Type getParameterType ( DeclarationPosition dpos , TypePath path ) {
569- exists ( Param p , int i , boolean inMethod |
570- paramPos ( this .getParamList ( ) , p , i , inMethod ) and
571- dpos = TPositionalDeclarationPosition ( i , inMethod ) and
567+ exists ( Param p , int i |
568+ paramPos ( this .getParamList ( ) , p , i ) and
569+ dpos = TPositionalDeclarationPosition ( i ) and
572570 result = inferAnnotatedType ( p .getPat ( ) , path )
573571 )
574572 or
@@ -587,125 +585,44 @@ private module CallExprBaseMatchingInput implements MatchingInputSig {
587585 }
588586 }
589587
590- private predicate argPos ( CallExprBase call , Expr e , int pos , boolean isMethodCall ) {
591- exists ( ArgList al |
592- e = al .getArg ( pos ) and
593- call .getArgList ( ) = al and
594- if call instanceof MethodCallExpr then isMethodCall = true else isMethodCall = false
595- )
596- }
597-
598- private newtype TAccessPosition =
599- TSelfAccessPosition ( ) or
600- TPositionalAccessPosition ( int pos , boolean isMethodCall ) { argPos ( _, _, pos , isMethodCall ) } or
601- TReturnAccessPosition ( )
602-
603- class AccessPosition extends TAccessPosition {
604- predicate isSelf ( ) { this = TSelfAccessPosition ( ) }
605-
606- int asPosition ( boolean isMethodCall ) { this = TPositionalAccessPosition ( result , isMethodCall ) }
607-
608- predicate isReturn ( ) { this = TReturnAccessPosition ( ) }
609-
610- string toString ( ) {
611- this .isSelf ( ) and
612- result = "self"
613- or
614- result = this .asPosition ( _) .toString ( )
615- or
616- this .isReturn ( ) and
617- result = "(return)"
618- }
619- }
588+ class AccessPosition = DeclarationPosition ;
620589
621590 private import codeql.rust.elements.internal.CallExprImpl:: Impl as CallExprImpl
622591
623- abstract class Access extends Expr {
624- abstract Type getTypeArgument ( TypeArgumentPosition apos , TypePath path ) ;
625-
626- abstract AstNode getNodeAt ( AccessPosition apos ) ;
627-
628- abstract Type getInferredType ( AccessPosition apos , TypePath path ) ;
629-
630- abstract Declaration getTarget ( ) ;
631- }
632-
633- private class CallExprBaseAccess extends Access instanceof CallExprBase {
634- private TypeMention getMethodTypeArg ( int i ) {
635- result = this .( MethodCallExpr ) .getGenericArgList ( ) .getTypeArg ( i )
636- }
637-
638- override Type getTypeArgument ( TypeArgumentPosition apos , TypePath path ) {
592+ final class Access extends Call {
593+ Type getTypeArgument ( TypeArgumentPosition apos , TypePath path ) {
639594 exists ( TypeMention arg | result = arg .resolveTypeAt ( path ) |
640595 arg = getExplicitTypeArgMention ( CallExprImpl:: getFunctionPath ( this ) , apos .asTypeParam ( ) )
641596 or
642- arg = this .getMethodTypeArg ( apos .asMethodTypeArgumentPosition ( ) )
597+ arg =
598+ this .( MethodCallExpr ) .getGenericArgList ( ) .getTypeArg ( apos .asMethodTypeArgumentPosition ( ) )
643599 )
644600 }
645601
646- override AstNode getNodeAt ( AccessPosition apos ) {
647- exists ( int p , boolean isMethodCall |
648- argPos ( this , result , p , isMethodCall ) and
649- apos = TPositionalAccessPosition ( p , isMethodCall )
650- )
602+ AstNode getNodeAt ( AccessPosition apos ) {
603+ result = this .getArgument ( apos .asPosition ( ) )
651604 or
652- result = this .( MethodCallExpr ) .getReceiver ( ) and
653- apos = TSelfAccessPosition ( )
605+ result = this .getReceiver ( ) and apos .isSelf ( )
654606 or
655- result = this and
656- apos = TReturnAccessPosition ( )
607+ result = this and apos .isReturn ( )
657608 }
658609
659- override Type getInferredType ( AccessPosition apos , TypePath path ) {
610+ Type getInferredType ( AccessPosition apos , TypePath path ) {
660611 result = inferType ( this .getNodeAt ( apos ) , path )
661612 }
662613
663- override Declaration getTarget ( ) {
664- result = CallExprImpl:: getResolvedFunction ( this )
665- or
614+ Declaration getTarget ( ) {
666615 result = inferMethodCallTarget ( this ) // mutual recursion; resolving method calls requires resolving types and vice versa
667- }
668- }
669-
670- private class OperationAccess extends Access instanceof Operation {
671- OperationAccess ( ) { super .isOverloaded ( _, _) }
672-
673- override Type getTypeArgument ( TypeArgumentPosition apos , TypePath path ) {
674- // The syntax for operators does not allow type arguments.
675- none ( )
676- }
677-
678- override AstNode getNodeAt ( AccessPosition apos ) {
679- result = super .getOperand ( 0 ) and apos = TSelfAccessPosition ( )
680- or
681- result = super .getOperand ( 1 ) and apos = TPositionalAccessPosition ( 0 , true )
682616 or
683- result = this and apos = TReturnAccessPosition ( )
684- }
685-
686- override Type getInferredType ( AccessPosition apos , TypePath path ) {
687- result = inferType ( this .getNodeAt ( apos ) , path )
688- }
689-
690- override Declaration getTarget ( ) {
691- result = inferMethodCallTarget ( this ) // mutual recursion; resolving method calls requires resolving types and vice versa
617+ result = CallExprImpl:: getResolvedFunction ( this )
692618 }
693619 }
694620
695621 predicate accessDeclarationPositionMatch ( AccessPosition apos , DeclarationPosition dpos ) {
696622 apos .isSelf ( ) and
697623 dpos .isSelf ( )
698624 or
699- exists ( int pos , boolean isMethodCall | pos = apos .asPosition ( isMethodCall ) |
700- pos = 0 and
701- isMethodCall = false and
702- dpos .isSelf ( )
703- or
704- isMethodCall = false and
705- pos = dpos .asPosition ( true ) + 1
706- or
707- pos = dpos .asPosition ( isMethodCall )
708- )
625+ apos .asPosition ( ) = dpos .asPosition ( )
709626 or
710627 apos .isReturn ( ) and
711628 dpos .isReturn ( )
@@ -1010,91 +927,29 @@ private StructType inferLiteralType(LiteralExpr le) {
1010927 )
1011928}
1012929
1013- private module MethodCall {
1014- /** An expression that calls a method. */
1015- abstract private class MethodCallImpl extends Expr {
1016- /** Gets the name of the method targeted. */
1017- abstract string getMethodName ( ) ;
1018-
1019- /** Gets the number of arguments _excluding_ the `self` argument. */
1020- abstract int getArity ( ) ;
1021-
1022- /** Gets the trait targeted by this method call, if any. */
1023- Trait getTrait ( ) { none ( ) }
1024-
1025- /** Gets the type of the receiver of the method call at `path`. */
1026- abstract Type getTypeAt ( TypePath path ) ;
930+ final class MethodCall extends Call {
931+ MethodCall ( ) {
932+ exists ( this .getReceiver ( ) ) and
933+ // We want the method calls that don't have a path to a concrete method in
934+ // an impl block. We need to exclude calls like `MyType::my_method(..)`.
935+ ( this instanceof CallExpr implies exists ( this .getTrait ( ) ) )
1027936 }
1028937
1029- final class MethodCall = MethodCallImpl ;
1030-
1031- private class MethodCallExprMethodCall extends MethodCallImpl instanceof MethodCallExpr {
1032- override string getMethodName ( ) { result = super .getIdentifier ( ) .getText ( ) }
1033-
1034- override int getArity ( ) { result = super .getArgList ( ) .getNumberOfArgs ( ) }
1035-
1036- pragma [ nomagic]
1037- override Type getTypeAt ( TypePath path ) {
938+ /** Gets the type of the receiver of the method call at `path`. */
939+ Type getTypeAt ( TypePath path ) {
940+ if this .receiverImplicitlyBorrowed ( )
941+ then
1038942 exists ( TypePath path0 | result = inferType ( super .getReceiver ( ) , path0 ) |
1039943 path0 .isCons ( TRefTypeParameter ( ) , path )
1040944 or
1041945 not path0 .isCons ( TRefTypeParameter ( ) , _) and
1042946 not ( path0 .isEmpty ( ) and result = TRefType ( ) ) and
1043947 path = path0
1044948 )
1045- }
1046- }
1047-
1048- private class CallExprMethodCall extends MethodCallImpl instanceof CallExpr {
1049- TraitItemNode trait ;
1050- string methodName ;
1051- Expr receiver ;
1052-
1053- CallExprMethodCall ( ) {
1054- receiver = this .getArgList ( ) .getArg ( 0 ) and
1055- exists ( Path path , Function f |
1056- path = this .getFunction ( ) .( PathExpr ) .getPath ( ) and
1057- f = resolvePath ( path ) and
1058- f .getParamList ( ) .hasSelfParam ( ) and
1059- trait = resolvePath ( path .getQualifier ( ) ) and
1060- trait .getAnAssocItem ( ) = f and
1061- path .getSegment ( ) .getIdentifier ( ) .getText ( ) = methodName
1062- )
1063- }
1064-
1065- override string getMethodName ( ) { result = methodName }
1066-
1067- override int getArity ( ) { result = super .getArgList ( ) .getNumberOfArgs ( ) - 1 }
1068-
1069- override Trait getTrait ( ) { result = trait }
1070-
1071- pragma [ nomagic]
1072- override Type getTypeAt ( TypePath path ) { result = inferType ( receiver , path ) }
1073- }
1074-
1075- private class OperationMethodCall extends MethodCallImpl instanceof Operation {
1076- TraitItemNode trait ;
1077- string methodName ;
1078-
1079- OperationMethodCall ( ) { super .isOverloaded ( trait , methodName ) }
1080-
1081- override string getMethodName ( ) { result = methodName }
1082-
1083- override int getArity ( ) { result = this .( Operation ) .getNumberOfOperands ( ) - 1 }
1084-
1085- override Trait getTrait ( ) { result = trait }
1086-
1087- pragma [ nomagic]
1088- override Type getTypeAt ( TypePath path ) {
1089- result = inferType ( this .( BinaryExpr ) .getLhs ( ) , path )
1090- or
1091- result = inferType ( this .( PrefixExpr ) .getExpr ( ) , path )
1092- }
949+ else result = inferType ( super .getReceiver ( ) , path )
1093950 }
1094951}
1095952
1096- import MethodCall
1097-
1098953/**
1099954 * Holds if a method for `type` with the name `name` and the arity `arity`
1100955 * exists in `impl`.
@@ -1124,7 +979,7 @@ private module IsInstantiationOfInput implements IsInstantiationOfInputSig<Metho
1124979 exists ( Type rootType , string name , int arity |
1125980 rootType = mc .getTypeAt ( TypePath:: nil ( ) ) and
1126981 name = mc .getMethodName ( ) and
1127- arity = mc .getArity ( ) and
982+ arity = mc .getNumberOfArguments ( ) and
1128983 constraint = impl .( ImplTypeAbstraction ) .getSelfTy ( )
1129984 |
1130985 methodCandidateTrait ( rootType , mc .getTrait ( ) , name , arity , impl )
0 commit comments