@@ -28,7 +28,7 @@ private newtype TTypeArgumentPosition =
2828 TMethodTypeArgumentPosition ( int pos ) {
2929 exists ( any ( MethodCallExpr mce ) .getGenericArgList ( ) .getTypeArg ( pos ) )
3030 } or
31- TTypeParamTypeArgumentPosition ( TypeParam tp )
31+ TTypeParamTypeArgumentPosition ( TypeParameter tp )
3232
3333private module Input1 implements InputSig1< Location > {
3434 private import Type as T
@@ -46,46 +46,35 @@ private module Input1 implements InputSig1<Location> {
4646 class TypeArgumentPosition extends TTypeArgumentPosition {
4747 int asMethodTypeArgumentPosition ( ) { this = TMethodTypeArgumentPosition ( result ) }
4848
49- TypeParam asTypeParam ( ) { this = TTypeParamTypeArgumentPosition ( result ) }
49+ TypeParameter asTypeParameter ( ) { this = TTypeParamTypeArgumentPosition ( result ) }
50+
51+ TypeParam asTypeParam ( ) {
52+ result = this .asTypeParameter ( ) .( TypeParamTypeParameter ) .getTypeParam ( )
53+ }
5054
5155 string toString ( ) {
5256 result = this .asMethodTypeArgumentPosition ( ) .toString ( )
5357 or
54- result = this .asTypeParam ( ) .toString ( )
58+ result = this .asTypeParameter ( ) .toString ( )
5559 }
5660 }
5761
58- private newtype TTypeParameterPosition =
59- TTypeParamTypeParameterPosition ( TypeParam tp ) or
60- TImplicitTypeParameterPosition ( )
62+ private newtype TTypeParameterPosition = TTypeParamTypeParameterPosition ( TypeParameter tp )
6163
6264 class TypeParameterPosition extends TTypeParameterPosition {
63- TypeParam asTypeParam ( ) { this = TTypeParamTypeParameterPosition ( result ) }
64-
65- /**
66- * Holds if this is the implicit type parameter position used to represent
67- * parameters that are never passed explicitly as arguments.
68- */
69- predicate isImplicit ( ) { this = TImplicitTypeParameterPosition ( ) }
65+ TypeParameter asTypeParameter ( ) { this = TTypeParamTypeParameterPosition ( result ) }
7066
71- string toString ( ) {
72- result = this .asTypeParam ( ) .toString ( )
73- or
74- result = "Implicit" and this .isImplicit ( )
67+ TypeParam asTypeParam ( ) {
68+ result = this .asTypeParameter ( ) .( TypeParamTypeParameter ) .getTypeParam ( )
7569 }
76- }
7770
78- /** Holds if `typeParam`, `param` and `ppos` all concern the same `TypeParam`. */
79- additional predicate typeParamMatchPosition (
80- TypeParam typeParam , TypeParamTypeParameter param , TypeParameterPosition ppos
81- ) {
82- typeParam = param .getTypeParam ( ) and typeParam = ppos .asTypeParam ( )
71+ string toString ( ) { result = this .asTypeParameter ( ) .toString ( ) }
8372 }
8473
8574 bindingset [ apos]
8675 bindingset [ ppos]
8776 predicate typeArgumentParameterPositionMatch ( TypeArgumentPosition apos , TypeParameterPosition ppos ) {
88- apos .asTypeParam ( ) = ppos .asTypeParam ( )
77+ apos .asTypeParameter ( ) = ppos .asTypeParameter ( )
8978 or
9079 apos .asMethodTypeArgumentPosition ( ) = ppos .asTypeParam ( ) .getPosition ( )
9180 }
@@ -420,8 +409,6 @@ private module Input3 implements InputSig3 {
420409
421410 class CallResolutionContext = FunctionCallMatchingInput:: AccessEnvironment ;
422411
423- class TypePosition = FunctionPosition ;
424-
425412 class Callable extends FunctionCallMatchingInput:: Declaration {
426413 TypeMention getAdditionalTypeParameterConstraint ( TypeParameter tp ) {
427414 result =
@@ -430,20 +417,39 @@ private module Input3 implements InputSig3 {
430417 .getAdditionalTypeBound ( this .getFunction ( ) , _)
431418 .getTypeRepr ( )
432419 }
420+
421+ Type getParameterType ( int j , TypePath path ) {
422+ exists ( FunctionPosition pos | j = pos .asPosition ( ) | result = this .getDeclaredType ( pos , path ) )
423+ }
424+
425+ Type getReturnType ( TypePath path ) {
426+ exists ( FunctionPosition pos | pos .isReturn ( ) | result = this .getDeclaredType ( pos , path ) )
427+ }
433428 }
434429
435430 class Call extends FunctionCallMatchingInput:: Access {
436431 Callable getTarget ( string derefChainBorrow ) { result = super .getTarget ( derefChainBorrow ) }
432+
433+ AstNode getArgument ( int i ) {
434+ exists ( FunctionPosition pos |
435+ result = this .getNodeAt ( pos ) and
436+ i = pos .asPosition ( )
437+ )
438+ }
437439 }
438440
439441 bindingset [ derefChainBorrow]
440- Type inferCallTypeAtPos ( Call call , string derefChainBorrow , FunctionPosition pos , TypePath path ) {
441- result = call .( FunctionCallMatchingInput:: Access ) .getInferredType ( derefChainBorrow , pos , path )
442+ Type inferCallArgumentType ( Call call , string derefChainBorrow , int i , TypePath path ) {
443+ exists ( FunctionPosition pos |
444+ i = pos .asPosition ( ) and
445+ result = call .( FunctionCallMatchingInput:: Access ) .getInferredType ( derefChainBorrow , pos , path )
446+ )
442447 }
443448
444449 Type inferCallReturnType ( AstNode n , TypePath path ) {
445450 exists ( Call call , TypePath path0 |
446- result = M3:: inferCallReturnType ( call , _, n , path0 ) and
451+ result = M3:: inferCallReturnType ( call , _, path0 ) and
452+ n = call and
447453 if
448454 // index expression `x[i]` desugars to `*x.index(i)`, so we must account for
449455 // the implicit deref
@@ -455,7 +461,7 @@ private module Input3 implements InputSig3 {
455461
456462 Type inferCallArgumentType ( AstNode n , TypePath path ) {
457463 exists ( FunctionCallMatchingInput:: Access call , FunctionPosition pos |
458- result = inferCallArgumentType ( call , pos , n , _, _, path ) and
464+ result = inferCallArgumentType ( call , pos . asPosition ( ) , n , _, _, path ) and
459465 not call .( AssocFunctionResolution:: AssocFunctionCall ) .hasReceiverAtPos ( pos )
460466 )
461467 or
@@ -733,20 +739,22 @@ private class FunctionDeclaration extends Function {
733739 }
734740
735741 TypeParameter getTypeParameter ( ImplOrTraitItemNodeOption i , TypeParameterPosition ppos ) {
736- typeParamMatchPosition ( this .getTypeParam ( i ) , result , ppos )
737- or
738- // For every `TypeParam` of this function, any associated types accessed on
739- // the type parameter are also type parameters.
740- ppos .isImplicit ( ) and
741- result .( TypeParamAssociatedTypeTypeParameter ) .getTypeParam ( ) = this .getTypeParam ( i )
742- or
743- i = parent and
742+ result = ppos .asTypeParameter ( ) and
744743 (
745- ppos .isImplicit ( ) and result = TSelfTypeParameter ( i . asSome ( ) )
744+ ppos .asTypeParam ( ) = this . getTypeParam ( i )
746745 or
747- ppos .isImplicit ( ) and result .( AssociatedTypeTypeParameter ) .getTrait ( ) = i .asSome ( )
746+ // For every `TypeParam` of this function, any associated types accessed on
747+ // the type parameter are also type parameters.
748+ result .( TypeParamAssociatedTypeTypeParameter ) .getTypeParam ( ) = this .getTypeParam ( i )
748749 or
749- ppos .isImplicit ( ) and this = result .( ImplTraitTypeTypeParameter ) .getFunction ( )
750+ i = parent and
751+ (
752+ result = TSelfTypeParameter ( i .asSome ( ) )
753+ or
754+ result .( AssociatedTypeTypeParameter ) .getTrait ( ) = i .asSome ( )
755+ or
756+ this = result .( ImplTraitTypeTypeParameter ) .getFunction ( )
757+ )
750758 )
751759 }
752760
@@ -810,27 +818,39 @@ private TypePath getPathToImplSelfTypeParam(TypeParam tp) {
810818
811819pragma [ nomagic]
812820private Type getCallExprTypeArgument ( CallExpr ce , TypeArgumentPosition apos , TypePath path ) {
813- exists ( Path p , ItemNode resolved , TypeParam tp |
821+ exists ( Path p , ItemNode resolved , TypeParameter tp |
814822 p = CallExprImpl:: getFunctionPath ( ce ) and
815823 resolved = resolvePath ( p ) and
816- apos .asTypeParam ( ) = tp
824+ apos .asTypeParameter ( ) = tp
817825 |
818- // For type parameters of the function we must resolve their
819- // instantiation from the path. For instance, for `fn bar<A>(a: A) -> A`
820- // and the path `bar<i64>`, we must resolve `A` to `i64`.
821- exists ( int i |
822- tp = resolved .getTypeParam ( pragma [ only_bind_into ] ( i ) ) and
823- result = getPathTypeArgument ( p , pragma [ only_bind_into ] ( i ) ) .getTypeAt ( path )
826+ exists ( TypeParam param | param = tp .( TypeParamTypeParameter ) .getTypeParam ( ) |
827+ // For type parameters of the function we must resolve their
828+ // instantiation from the path. For instance, for `fn bar<A>(a: A) -> A`
829+ // and the path `bar<i64>`, we must resolve `A` to `i64`.
830+ exists ( int i |
831+ param = resolved .getTypeParam ( pragma [ only_bind_into ] ( i ) ) and
832+ result = getPathTypeArgument ( p , pragma [ only_bind_into ] ( i ) ) .getTypeAt ( path )
833+ )
834+ or
835+ // For type parameters of the `impl` block we must resolve their
836+ // instantiation from the path. For instance, for `impl<A> for Foo<A>`
837+ // and the path `Foo<i64>::bar` we must resolve `A` to `i64`.
838+ exists ( ImplItemNode impl , TypePath pathToTp |
839+ resolved = impl .getASuccessor ( _) and
840+ param = impl .getTypeParam ( _) and
841+ pathToTp = getPathToImplSelfTypeParam ( param ) and
842+ result = p .getQualifier ( ) .( TypeMention ) .getTypeAt ( pathToTp .appendInverse ( path ) )
843+ )
824844 )
825845 or
826- // For type parameters of the `impl` block we must resolve their
827- // instantiation from the path. For instance, for `impl<A> for Foo<A>`
828- // and the path `Foo<i64>::bar` we must resolve `A` to `i64`.
829- exists ( ImplItemNode impl , TypePath pathToTp |
830- resolved = impl . getASuccessor ( _ ) and
831- tp = impl . getTypeParam ( _ ) and
832- pathToTp = getPathToImplSelfTypeParam ( tp ) and
833- result = p . getQualifier ( ) . ( TypeMention ) .getTypeAt ( pathToTp . appendInverse ( path ) )
846+ // In calls like `T::default()` where `T` is a type parameter with a `Default` constraint,
847+ // we consider `T` to be an explicit type argument for the implicit `Self` type parameter.
848+ exists ( TraitItemNode trait , TypeMention qualifier |
849+ resolved = trait . getASuccessor ( _ ) and
850+ tp = TSelfTypeParameter ( trait ) and
851+ qualifier = p . getQualifier ( ) and
852+ result = qualifier . ( TypeMention ) . getTypeAt ( path ) and
853+ not qualifier . ( TypeMention ) .getType ( ) instanceof TraitType
834854 )
835855 )
836856 or
@@ -2833,7 +2853,7 @@ private module FunctionCallMatchingInput implements MatchingWithEnvironmentInput
28332853
28342854pragma [ nomagic]
28352855private Type inferCallArgumentType (
2836- FunctionCallMatchingInput:: Access call , FunctionPosition pos , AstNode n , DerefChain derefChain ,
2856+ FunctionCallMatchingInput:: Access call , int pos , AstNode n , DerefChain derefChain ,
28372857 BorrowKind borrow , TypePath path
28382858) {
28392859 exists ( string derefChainBorrow |
@@ -2855,7 +2875,7 @@ private Type inferFunctionCallSelfArgumentType(
28552875) {
28562876 exists ( FunctionPosition pos , BorrowKind borrow , TypePath path0 |
28572877 call .( AssocFunctionResolution:: AssocFunctionCall ) .hasReceiverAtPos ( pos ) and
2858- result = inferCallArgumentType ( call , pos , n , derefChain , borrow , path0 )
2878+ result = inferCallArgumentType ( call , pos . asPosition ( ) , n , derefChain , borrow , path0 )
28592879 |
28602880 borrow .isNoBorrow ( ) and
28612881 path = path0
@@ -2891,7 +2911,8 @@ private Type inferFunctionCallSelfArgumentType(
28912911
28922912abstract private class Constructor extends Addressable {
28932913 final TypeParameter getTypeParameter ( TypeParameterPosition ppos ) {
2894- typeParamMatchPosition ( this .getTypeItem ( ) .getGenericParamList ( ) .getATypeParam ( ) , result , ppos )
2914+ result = ppos .asTypeParameter ( ) and
2915+ ppos .asTypeParam ( ) = this .getTypeItem ( ) .getGenericParamList ( ) .getATypeParam ( )
28952916 }
28962917
28972918 abstract TypeItem getTypeItem ( ) ;
0 commit comments