@@ -582,6 +582,137 @@ private module Input3 implements InputSig3 {
582582 }
583583 }
584584
585+ final class Constructor = ConstructorImpl ;
586+
587+ abstract private class ConstructorImpl extends Addressable {
588+ TypeMention getAdditionalTypeParameterConstraint ( TypeParameter tp ) { none ( ) }
589+
590+ final TypeParameter getTypeParameter ( TypeParameterPosition ppos ) {
591+ result = ppos .asTypeParameter ( ) and
592+ ppos .asTypeParam ( ) = this .getTypeItem ( ) .getGenericParamList ( ) .getATypeParam ( )
593+ }
594+
595+ abstract TypeItem getTypeItem ( ) ;
596+
597+ abstract TypeRepr getParameterTypeRepr ( int pos ) ;
598+
599+ Type getParameterType ( int pos , TypePath path ) {
600+ result = this .getParameterTypeRepr ( pos ) .( TypeMention ) .getTypeAt ( path )
601+ }
602+
603+ Type getReturnType ( TypePath path ) {
604+ result = TDataType ( this .getTypeItem ( ) ) and
605+ path .isEmpty ( )
606+ or
607+ result = TTypeParamTypeParameter ( this .getTypeItem ( ) .getGenericParamList ( ) .getATypeParam ( ) ) and
608+ path = TypePath:: singleton ( result )
609+ }
610+ }
611+
612+ private class StructConstructor extends ConstructorImpl instanceof Struct {
613+ override TypeItem getTypeItem ( ) { result = this }
614+
615+ override TypeRepr getParameterTypeRepr ( int i ) {
616+ result = [ super .getTupleField ( i ) .getTypeRepr ( ) , super .getNthStructField ( i ) .getTypeRepr ( ) ]
617+ }
618+ }
619+
620+ private class VariantConstructor extends ConstructorImpl instanceof Variant {
621+ override TypeItem getTypeItem ( ) { result = super .getEnum ( ) }
622+
623+ override TypeRepr getParameterTypeRepr ( int i ) {
624+ result = [ super .getTupleField ( i ) .getTypeRepr ( ) , super .getNthStructField ( i ) .getTypeRepr ( ) ]
625+ }
626+ }
627+
628+ abstract class Construction extends Expr {
629+ abstract Constructor getTarget ( ) ;
630+
631+ abstract AstNode getArgument ( int i ) ;
632+
633+ abstract Type getTypeArgument ( TypeArgumentPosition apos , TypePath path ) ;
634+
635+ /**
636+ * Holds if the return type of this construction expression at `path` may
637+ * have to be inferred from the context. For example in `Result::Ok(42)` the
638+ * error type has to be inferred from the context.
639+ */
640+ pragma [ nomagic]
641+ predicate hasUnknownReturnTypeAt ( TypePath path ) {
642+ exists ( Constructor c , TypeParameter tp |
643+ c = this .getTarget ( ) and
644+ tp = c .getReturnType ( path ) and
645+ not tp = c .getParameterType ( _, _) and
646+ // check that no explicit type arguments have been supplied for `tp`
647+ not exists ( TypeArgumentPosition tapos |
648+ this .getTypeArgument ( tapos , _) != TUnknownType ( ) and
649+ TTypeParamTypeParameter ( tapos .asTypeParam ( ) ) = tp
650+ )
651+ )
652+ }
653+ }
654+
655+ private class NonAssocCallConstruction extends Construction , NonAssocCallExpr ,
656+ ContextualTyping:: ContextuallyTypedCallCand
657+ {
658+ NonAssocCallConstruction ( ) {
659+ this instanceof CallExprImpl:: TupleStructExpr or
660+ this instanceof CallExprImpl:: TupleVariantExpr
661+ }
662+
663+ override Type getTypeArgument ( TypeArgumentPosition apos , TypePath path ) {
664+ result = NonAssocCallExpr .super .getTypeArgument ( apos , path )
665+ }
666+
667+ override AstNode getArgument ( int i ) {
668+ exists ( FunctionPosition pos |
669+ i = pos .asPosition ( ) and
670+ result = NonAssocCallExpr .super .getNodeAt ( pos )
671+ )
672+ }
673+
674+ override Constructor getTarget ( ) { result = this .resolveCallTargetViaPathResolution ( ) }
675+ }
676+
677+ abstract private class StructConstruction extends Construction instanceof PathAstNode {
678+ pragma [ nomagic]
679+ override Constructor getTarget ( ) { result = resolvePath ( super .getPath ( ) ) }
680+
681+ pragma [ nomagic]
682+ override Type getTypeArgument ( TypeArgumentPosition apos , TypePath path ) {
683+ // Handle constructions that use `Self {...}` syntax
684+ exists ( TypeMention tm , TypePath path0 |
685+ tm = super .getPath ( ) and
686+ result = tm .getTypeAt ( path0 ) and
687+ path0 .isCons ( TTypeParamTypeParameter ( apos .asTypeParam ( ) ) , path )
688+ )
689+ }
690+ }
691+
692+ private class StructExprConstruction extends StructConstruction , StructExpr {
693+ override Type getTypeArgument ( TypeArgumentPosition apos , TypePath path ) {
694+ result = super .getTypeArgument ( apos , path )
695+ or
696+ exists ( TypePath suffix |
697+ suffix .isCons ( TTypeParamTypeParameter ( apos .asTypeParam ( ) ) , path ) and
698+ result = inferTypeCertain ( this , suffix )
699+ )
700+ }
701+
702+ override AstNode getArgument ( int i ) {
703+ result =
704+ this .getFieldExpr ( pragma [ only_bind_into ] ( this .getNthStructField ( i ) .getName ( ) .getText ( ) ) )
705+ .getExpr ( )
706+ }
707+ }
708+
709+ /** A potential nullary struct/variant construction such as `None`. */
710+ private class PathExprConstruction extends StructConstruction , PathExpr {
711+ PathExprConstruction ( ) { not exists ( CallExpr ce | this = ce .getFunction ( ) ) }
712+
713+ override AstNode getArgument ( int i ) { none ( ) }
714+ }
715+
585716 predicate inferStepCertain ( AstNode n1 , TypePath path1 , AstNode n2 , TypePath path2 ) {
586717 n1 =
587718 any ( IdentPat ip |
@@ -756,8 +887,6 @@ private module Input3 implements InputSig3 {
756887 or
757888 result = inferAssignmentOperationType ( n , path )
758889 or
759- exists ( FunctionPosition pos | pos .isReturn ( ) | result = inferConstructionType ( n , pos , path ) )
760- or
761890 result = inferTryExprType ( n , path )
762891 or
763892 result = inferLiteralType ( n , path , false )
@@ -776,10 +905,6 @@ private module Input3 implements InputSig3 {
776905 or
777906 result = inferUnknownType ( n , path )
778907 }
779-
780- Type inferTypeTopDown ( AstNode n , TypePath path ) {
781- exists ( FunctionPosition pos | not pos .isReturn ( ) | result = inferConstructionType ( n , pos , path ) )
782- }
783908}
784909
785910private module M3 = Make3< Input3 > ;
@@ -3008,172 +3133,6 @@ private Type inferFunctionCallSelfArgumentTypeContextual(
30083133 )
30093134}
30103135
3011- abstract private class Constructor extends Addressable {
3012- final TypeParameter getTypeParameter ( TypeParameterPosition ppos ) {
3013- result = ppos .asTypeParameter ( ) and
3014- ppos .asTypeParam ( ) = this .getTypeItem ( ) .getGenericParamList ( ) .getATypeParam ( )
3015- }
3016-
3017- abstract TypeItem getTypeItem ( ) ;
3018-
3019- abstract TypeRepr getParameterTypeRepr ( int pos ) ;
3020-
3021- Type getParameterType ( int pos , TypePath path ) {
3022- result = this .getParameterTypeRepr ( pos ) .( TypeMention ) .getTypeAt ( path )
3023- }
3024-
3025- Type getReturnType ( TypePath path ) {
3026- result = TDataType ( this .getTypeItem ( ) ) and
3027- path .isEmpty ( )
3028- or
3029- result = TTypeParamTypeParameter ( this .getTypeItem ( ) .getGenericParamList ( ) .getATypeParam ( ) ) and
3030- path = TypePath:: singleton ( result )
3031- }
3032-
3033- Type getDeclaredType ( FunctionPosition pos , TypePath path ) {
3034- result = this .getParameterType ( pos .asPosition ( ) , path )
3035- or
3036- pos .isReturn ( ) and
3037- result = this .getReturnType ( path )
3038- }
3039- }
3040-
3041- private class StructConstructor extends Constructor instanceof Struct {
3042- override TypeItem getTypeItem ( ) { result = this }
3043-
3044- override TypeRepr getParameterTypeRepr ( int i ) {
3045- result = [ super .getTupleField ( i ) .getTypeRepr ( ) , super .getNthStructField ( i ) .getTypeRepr ( ) ]
3046- }
3047- }
3048-
3049- private class VariantConstructor extends Constructor instanceof Variant {
3050- override TypeItem getTypeItem ( ) { result = super .getEnum ( ) }
3051-
3052- override TypeRepr getParameterTypeRepr ( int i ) {
3053- result = [ super .getTupleField ( i ) .getTypeRepr ( ) , super .getNthStructField ( i ) .getTypeRepr ( ) ]
3054- }
3055- }
3056-
3057- /**
3058- * A matching configuration for resolving types of constructions of enums and
3059- * structs, such as `Result::Ok(42)`, `Foo { bar: 1 }` and `None`.
3060- */
3061- private module ConstructionMatchingInput implements MatchingInputSig {
3062- import FunctionPositionMatchingInput
3063-
3064- class Declaration = Constructor ;
3065-
3066- abstract class Access extends AstNode {
3067- abstract Type getInferredType ( FunctionPosition pos , TypePath path ) ;
3068-
3069- abstract Declaration getTarget ( ) ;
3070-
3071- abstract AstNode getNodeAt ( AccessPosition apos ) ;
3072-
3073- abstract Type getTypeArgument ( TypeArgumentPosition apos , TypePath path ) ;
3074-
3075- /**
3076- * Holds if the return type of this construction expression at `path` may
3077- * have to be inferred from the context. For example in `Result::Ok(42)` the
3078- * error type has to be inferred from the context.
3079- */
3080- pragma [ nomagic]
3081- predicate hasUnknownTypeAt ( FunctionPosition pos , TypePath path ) {
3082- exists ( Declaration d , TypeParameter tp |
3083- d = this .getTarget ( ) and
3084- pos .isReturn ( ) and
3085- tp = d .getReturnType ( path ) and
3086- not exists ( FunctionPosition pos2 | not pos2 .isReturn ( ) and tp = d .getDeclaredType ( pos2 , _) ) and
3087- // check that no explicit type arguments have been supplied for `tp`
3088- not exists ( TypeArgumentPosition tapos |
3089- this .getTypeArgument ( tapos , _) != TUnknownType ( ) and
3090- TTypeParamTypeParameter ( tapos .asTypeParam ( ) ) = tp
3091- )
3092- )
3093- }
3094- }
3095-
3096- private class NonAssocCallAccess extends Access , NonAssocCallExpr ,
3097- ContextualTyping:: ContextuallyTypedCallCand
3098- {
3099- NonAssocCallAccess ( ) {
3100- this instanceof CallExprImpl:: TupleStructExpr or
3101- this instanceof CallExprImpl:: TupleVariantExpr
3102- }
3103-
3104- override Type getTypeArgument ( TypeArgumentPosition apos , TypePath path ) {
3105- result = NonAssocCallExpr .super .getTypeArgument ( apos , path )
3106- }
3107-
3108- override AstNode getNodeAt ( AccessPosition apos ) {
3109- result = NonAssocCallExpr .super .getNodeAt ( apos )
3110- }
3111-
3112- override Type getInferredType ( FunctionPosition pos , TypePath path ) {
3113- result = NonAssocCallExpr .super .getInferredType ( pos , path )
3114- }
3115-
3116- override Declaration getTarget ( ) { result = this .resolveCallTargetViaPathResolution ( ) }
3117- }
3118-
3119- abstract private class StructAccess extends Access instanceof PathAstNode {
3120- pragma [ nomagic]
3121- override Type getInferredType ( AccessPosition apos , TypePath path ) {
3122- result = inferType ( this .getNodeAt ( apos ) , path )
3123- }
3124-
3125- pragma [ nomagic]
3126- override Declaration getTarget ( ) { result = resolvePath ( super .getPath ( ) ) }
3127-
3128- pragma [ nomagic]
3129- override Type getTypeArgument ( TypeArgumentPosition apos , TypePath path ) {
3130- // Handle constructions that use `Self {...}` syntax
3131- exists ( TypeMention tm , TypePath path0 |
3132- tm = super .getPath ( ) and
3133- result = tm .getTypeAt ( path0 ) and
3134- path0 .isCons ( TTypeParamTypeParameter ( apos .asTypeParam ( ) ) , path )
3135- )
3136- }
3137- }
3138-
3139- private class StructExprAccess extends StructAccess , StructExpr {
3140- override Type getTypeArgument ( TypeArgumentPosition apos , TypePath path ) {
3141- result = super .getTypeArgument ( apos , path )
3142- or
3143- exists ( TypePath suffix |
3144- suffix .isCons ( TTypeParamTypeParameter ( apos .asTypeParam ( ) ) , path ) and
3145- result = inferTypeCertain ( this , suffix )
3146- )
3147- }
3148-
3149- override AstNode getNodeAt ( AccessPosition apos ) {
3150- result =
3151- this .getFieldExpr ( pragma [ only_bind_into ] ( this .getNthStructField ( apos .asPosition ( ) )
3152- .getName ( )
3153- .getText ( ) ) ) .getExpr ( )
3154- or
3155- result = this and apos .isReturn ( )
3156- }
3157- }
3158-
3159- /** A potential nullary struct/variant construction such as `None`. */
3160- private class PathExprAccess extends StructAccess , PathExpr {
3161- PathExprAccess ( ) { not exists ( CallExpr ce | this = ce .getFunction ( ) ) }
3162-
3163- override AstNode getNodeAt ( AccessPosition apos ) { result = this and apos .isReturn ( ) }
3164- }
3165- }
3166-
3167- private module ConstructionMatching = Matching< ConstructionMatchingInput > ;
3168-
3169- pragma [ nomagic]
3170- private Type inferConstructionType ( AstNode n , FunctionPosition pos , TypePath path ) {
3171- exists ( ConstructionMatchingInput:: Access a |
3172- n = a .getNodeAt ( pos ) and
3173- result = ConstructionMatching:: inferAccessType ( a , pos , path )
3174- )
3175- }
3176-
31773136pragma [ nomagic]
31783137private Type inferUnknownType ( AstNode n , TypePath path ) {
31793138 result = TUnknownType ( ) and
@@ -3183,10 +3142,7 @@ private Type inferUnknownType(AstNode n, TypePath path) {
31833142 call .hasUnknownTypeAt ( _, pos , path )
31843143 )
31853144 or
3186- exists ( ConstructionMatchingInput:: Access a , FunctionPosition pos |
3187- n = a .getNodeAt ( pos ) and
3188- a .hasUnknownTypeAt ( pos , path )
3189- )
3145+ n .( Input3:: Construction ) .hasUnknownReturnTypeAt ( path )
31903146 or
31913147 exists ( Param p |
31923148 not p .hasTypeRepr ( ) and
@@ -3452,7 +3408,14 @@ private Type inferDereferencedExprPtrType(AstNode n, TypePath path) {
34523408private module DeconstructionPatMatchingInput implements MatchingInputSig {
34533409 import FunctionPositionMatchingInput
34543410
3455- class Declaration = ConstructionMatchingInput:: Declaration ;
3411+ class Declaration extends Input3:: Constructor {
3412+ Type getDeclaredType ( FunctionPosition pos , TypePath path ) {
3413+ result = this .getParameterType ( pos .asPosition ( ) , path )
3414+ or
3415+ pos .isReturn ( ) and
3416+ result = this .getReturnType ( path )
3417+ }
3418+ }
34563419
34573420 class Access extends Pat instanceof PathAstNode {
34583421 Access ( ) { this instanceof TupleStructPat or this instanceof StructPat }
0 commit comments