@@ -271,6 +271,7 @@ import M2
271271
272272private module Input3 implements InputSig3 {
273273 private import rust as Rust
274+ private import codeql.rust.elements.internal.OperationImpl:: Impl as OperationImpl
274275
275276 predicate cacheRevRef ( ) {
276277 Stages:: TypeInferenceStage:: ref ( )
@@ -420,7 +421,7 @@ private module Input3 implements InputSig3 {
420421
421422 class CallResolutionContext = FunctionCallMatchingInput:: AccessEnvironment ;
422423
423- class Callable extends FunctionCallMatchingInput:: Declaration {
424+ final class Callable extends FunctionCallMatchingInput:: Declaration {
424425 TypeMention getAdditionalTypeParameterConstraint ( TypeParameter tp ) {
425426 result =
426427 tp .( TypeParamTypeParameter )
@@ -527,6 +528,60 @@ private module Input3 implements InputSig3 {
527528 )
528529 }
529530
531+ class Operator extends Callable {
532+ private Method getSelfOrImpl ( ) {
533+ result = f
534+ or
535+ f .implements ( result )
536+ }
537+
538+ pragma [ nomagic]
539+ private predicate borrowsAt ( int pos ) {
540+ exists ( TraitItemNode t , string path , string method |
541+ this .getSelfOrImpl ( ) = t .getAssocItem ( method ) and
542+ path = t .getCanonicalPath ( _) and
543+ exists ( int borrows | OperationImpl:: isOverloaded ( _, _, path , method , borrows ) |
544+ pos = 0 and borrows >= 1
545+ or
546+ pos = 1 and
547+ borrows >= 2
548+ )
549+ )
550+ }
551+
552+ pragma [ nomagic]
553+ private predicate derefsReturn ( ) { this .getSelfOrImpl ( ) = any ( DerefTrait t ) .getDerefFunction ( ) }
554+
555+ Type getParameterType ( int pos , TypePath path ) {
556+ exists ( TypePath path0 | result = super .getParameterType ( pos , path0 ) |
557+ if this .borrowsAt ( pos ) then path0 .isCons ( getRefTypeParameter ( _) , path ) else path0 = path
558+ )
559+ }
560+
561+ Type getReturnType ( TypePath path ) {
562+ exists ( TypePath path0 | result = super .getReturnType ( path0 ) |
563+ if this .derefsReturn ( ) then path0 .isCons ( getRefTypeParameter ( _) , path ) else path0 = path
564+ )
565+ }
566+ }
567+
568+ class Operation extends AssocFunctionResolution:: OperationAssocFunctionCall {
569+ Type getTypeArgument ( TypeArgumentPosition apos , TypePath path ) { none ( ) }
570+
571+ AstNode getOperand ( int i ) {
572+ exists ( FunctionPosition pos |
573+ result = this .getNodeAt ( pos ) and
574+ i = pos .asPosition ( )
575+ )
576+ }
577+
578+ Operator getTarget ( ) {
579+ exists ( ImplOrTraitItemNode i |
580+ result .isAssocFunction ( i , this .resolveCallTarget ( i , _, _, _) , false ) // mutual recursion
581+ )
582+ }
583+ }
584+
530585 predicate inferStepCertain ( AstNode n1 , TypePath path1 , AstNode n2 , TypePath path2 ) {
531586 n1 =
532587 any ( IdentPat ip |
@@ -701,11 +756,7 @@ private module Input3 implements InputSig3 {
701756 or
702757 result = inferAssignmentOperationType ( n , path )
703758 or
704- exists ( FunctionPosition pos | pos .isReturn ( ) |
705- result = inferConstructionType ( n , pos , path )
706- or
707- result = inferOperationType ( n , pos , path )
708- )
759+ exists ( FunctionPosition pos | pos .isReturn ( ) | result = inferConstructionType ( n , pos , path ) )
709760 or
710761 result = inferTryExprType ( n , path )
711762 or
@@ -727,11 +778,7 @@ private module Input3 implements InputSig3 {
727778 }
728779
729780 Type inferTypeTopDown ( AstNode n , TypePath path ) {
730- exists ( FunctionPosition pos | not pos .isReturn ( ) |
731- result = inferConstructionType ( n , pos , path )
732- or
733- result = inferOperationType ( n , pos , path )
734- )
781+ exists ( FunctionPosition pos | not pos .isReturn ( ) | result = inferConstructionType ( n , pos , path ) )
735782 }
736783}
737784
@@ -3149,81 +3196,6 @@ private Type inferUnknownType(AstNode n, TypePath path) {
31493196 )
31503197}
31513198
3152- /**
3153- * A matching configuration for resolving types of operations like `a + b`.
3154- */
3155- private module OperationMatchingInput implements MatchingInputSig {
3156- private import codeql.rust.elements.internal.OperationImpl:: Impl as OperationImpl
3157- import FunctionPositionMatchingInput
3158-
3159- class Declaration extends FunctionCallMatchingInput:: Declaration {
3160- private Method getSelfOrImpl ( ) {
3161- result = f
3162- or
3163- f .implements ( result )
3164- }
3165-
3166- pragma [ nomagic]
3167- private predicate borrowsAt ( FunctionPosition pos ) {
3168- exists ( TraitItemNode t , string path , string method |
3169- this .getSelfOrImpl ( ) = t .getAssocItem ( method ) and
3170- path = t .getCanonicalPath ( _) and
3171- exists ( int borrows | OperationImpl:: isOverloaded ( _, _, path , method , borrows ) |
3172- pos .asPosition ( ) = 0 and borrows >= 1
3173- or
3174- pos .asPosition ( ) = 1 and
3175- borrows >= 2
3176- )
3177- )
3178- }
3179-
3180- pragma [ nomagic]
3181- private predicate derefsReturn ( ) { this .getSelfOrImpl ( ) = any ( DerefTrait t ) .getDerefFunction ( ) }
3182-
3183- Type getDeclaredType ( FunctionPosition pos , TypePath path ) {
3184- exists ( TypePath path0 |
3185- result = super .getParameterType ( pos .asPosition ( ) , path0 )
3186- or
3187- pos .isReturn ( ) and
3188- result = super .getReturnType ( path0 )
3189- |
3190- if
3191- this .borrowsAt ( pos )
3192- or
3193- pos .isReturn ( ) and this .derefsReturn ( )
3194- then path0 .isCons ( getRefTypeParameter ( _) , path )
3195- else path0 = path
3196- )
3197- }
3198- }
3199-
3200- class Access extends AssocFunctionResolution:: OperationAssocFunctionCall {
3201- Type getTypeArgument ( TypeArgumentPosition apos , TypePath path ) { none ( ) }
3202-
3203- pragma [ nomagic]
3204- Type getInferredType ( FunctionPosition pos , TypePath path ) {
3205- result = inferType ( this .getNodeAt ( pos ) , path )
3206- }
3207-
3208- Declaration getTarget ( ) {
3209- exists ( ImplOrTraitItemNode i |
3210- result .isAssocFunction ( i , this .resolveCallTarget ( i , _, _, _) , false ) // mutual recursion
3211- )
3212- }
3213- }
3214- }
3215-
3216- private module OperationMatching = Matching< OperationMatchingInput > ;
3217-
3218- pragma [ nomagic]
3219- private Type inferOperationType ( AstNode n , FunctionPosition pos , TypePath path ) {
3220- exists ( OperationMatchingInput:: Access a |
3221- n = a .getNodeAt ( pos ) and
3222- result = OperationMatching:: inferAccessType ( a , pos , path ) and
3223- if pos .asPosition ( ) = 0 then not path .isEmpty ( ) else any ( )
3224- )
3225- }
3226-
32273199pragma [ nomagic]
32283200private Type getFieldExprLookupType ( FieldExpr fe , string name , DerefChain derefChain ) {
32293201 exists ( TypePath path |
0 commit comments