@@ -461,6 +461,72 @@ private module Input3 implements InputSig3 {
461461 )
462462 }
463463
464+ abstract class Member extends AstNode {
465+ abstract TypeRepr getTypeRepr ( ) ;
466+
467+ Type getDeclaringType ( TypePath path ) {
468+ // no case for variants as those can only be destructured using pattern matching
469+ exists ( Struct s | this = [ s .getStructField ( _) .( AstNode ) , s .getTupleField ( _) ] |
470+ result = TDataType ( s ) and
471+ path .isEmpty ( )
472+ or
473+ result = TTypeParamTypeParameter ( s .getGenericParamList ( ) .getATypeParam ( ) ) and
474+ path = TypePath:: singleton ( result )
475+ )
476+ }
477+
478+ Type getDeclaredType ( TypePath path ) {
479+ result = this .getTypeRepr ( ) .( TypeMention ) .getTypeAt ( path )
480+ }
481+ }
482+
483+ private class StructFieldDecl extends Member instanceof StructField {
484+ override TypeRepr getTypeRepr ( ) { result = StructField .super .getTypeRepr ( ) }
485+ }
486+
487+ private class TupleFieldDecl extends Member instanceof TupleField {
488+ override TypeRepr getTypeRepr ( ) { result = TupleField .super .getTypeRepr ( ) }
489+ }
490+
491+ class MemberAccess extends FieldExpr {
492+ AstNode getReceiver ( ) { result = this .getContainer ( ) }
493+
494+ Member getMember ( ) {
495+ // mutual recursion; resolving fields requires resolving types and vice versa
496+ result =
497+ [
498+ resolveStructFieldExpr ( this , _) .( AstNode ) ,
499+ resolveTupleFieldExpr ( this , _)
500+ ]
501+ }
502+ }
503+
504+ Type inferMemberAccessReceiverType ( MemberAccess ma , TypePath path ) {
505+ exists ( TypePath path0 | result = inferType ( ma .getReceiver ( ) , path0 ) |
506+ // adjust for implicit deref
507+ path0 .isCons ( getRefTypeParameter ( _) , path )
508+ or
509+ not path0 .isCons ( getRefTypeParameter ( _) , _) and
510+ not ( result instanceof RefType and path0 .isEmpty ( ) ) and
511+ path = path0
512+ )
513+ }
514+
515+ Type inferMemberAccessReceiverTypeContextual ( AstNode n , TypePath path ) {
516+ exists ( TypePath path0 , Type receiverType |
517+ result = M3:: inferMemberAccessReceiverTypeContextualDefault ( _, n , path0 ) and
518+ receiverType = inferType ( n )
519+ |
520+ if receiverType instanceof RefType
521+ then
522+ // adjust for implicit deref
523+ not path0 .isCons ( getRefTypeParameter ( _) , _) and
524+ not ( path0 .isEmpty ( ) and result instanceof RefType ) and
525+ path = TypePath:: cons ( getRefTypeParameter ( _) , path0 )
526+ else path = path0
527+ )
528+ }
529+
464530 predicate inferStepCertain ( AstNode n1 , TypePath path1 , AstNode n2 , TypePath path2 ) {
465531 n1 =
466532 any ( IdentPat ip |
@@ -641,8 +707,6 @@ private module Input3 implements InputSig3 {
641707 result = inferOperationType ( n , pos , path )
642708 )
643709 or
644- result = inferFieldExprType ( n , path , false )
645- or
646710 result = inferTryExprType ( n , path )
647711 or
648712 result = inferLiteralType ( n , path , false )
@@ -668,8 +732,6 @@ private module Input3 implements InputSig3 {
668732 or
669733 result = inferOperationType ( n , pos , path )
670734 )
671- or
672- result = inferFieldExprType ( n , path , true )
673735 }
674736}
675737
@@ -2848,7 +2910,7 @@ private Type inferCallArgumentTypeContextual(
28482910) {
28492911 exists ( string derefChainBorrow |
28502912 FunctionCallMatchingInput:: decodeDerefChainBorrow ( derefChainBorrow , derefChain , borrow ) and
2851- result = M3:: inferCallArgumentTypeContextual ( call , derefChainBorrow , pos , n , path )
2913+ result = M3:: inferCallArgumentTypeContextualDefault ( call , derefChainBorrow , pos , n , path )
28522914 )
28532915}
28542916
@@ -3218,161 +3280,6 @@ TupleField resolveTupleFieldExpr(FieldExpr fe, DerefChain derefChain) {
32183280 )
32193281}
32203282
3221- /**
3222- * A matching configuration for resolving types of field expressions like `x.field`.
3223- */
3224- private module FieldExprMatchingInput implements MatchingInputSig {
3225- private newtype TDeclarationPosition =
3226- TSelfDeclarationPosition ( ) or
3227- TFieldPos ( )
3228-
3229- class DeclarationPosition extends TDeclarationPosition {
3230- predicate isSelf ( ) { this = TSelfDeclarationPosition ( ) }
3231-
3232- predicate isField ( ) { this = TFieldPos ( ) }
3233-
3234- string toString ( ) {
3235- this .isSelf ( ) and
3236- result = "self"
3237- or
3238- this .isField ( ) and
3239- result = "(field)"
3240- }
3241- }
3242-
3243- private newtype TDeclaration =
3244- TStructFieldDecl ( StructField sf ) or
3245- TTupleFieldDecl ( TupleField tf )
3246-
3247- abstract class Declaration extends TDeclaration {
3248- TypeParameter getTypeParameter ( TypeParameterPosition ppos ) { none ( ) }
3249-
3250- abstract Type getDeclaredType ( DeclarationPosition dpos , TypePath path ) ;
3251-
3252- abstract string toString ( ) ;
3253-
3254- abstract Location getLocation ( ) ;
3255- }
3256-
3257- abstract private class StructOrTupleFieldDecl extends Declaration {
3258- abstract AstNode getAstNode ( ) ;
3259-
3260- abstract TypeRepr getTypeRepr ( ) ;
3261-
3262- override Type getDeclaredType ( DeclarationPosition dpos , TypePath path ) {
3263- dpos .isSelf ( ) and
3264- // no case for variants as those can only be destructured using pattern matching
3265- exists ( Struct s | this .getAstNode ( ) = [ s .getStructField ( _) .( AstNode ) , s .getTupleField ( _) ] |
3266- result = TDataType ( s ) and
3267- path .isEmpty ( )
3268- or
3269- result = TTypeParamTypeParameter ( s .getGenericParamList ( ) .getATypeParam ( ) ) and
3270- path = TypePath:: singleton ( result )
3271- )
3272- or
3273- dpos .isField ( ) and
3274- result = this .getTypeRepr ( ) .( TypeMention ) .getTypeAt ( path )
3275- }
3276-
3277- override string toString ( ) { result = this .getAstNode ( ) .toString ( ) }
3278-
3279- override Location getLocation ( ) { result = this .getAstNode ( ) .getLocation ( ) }
3280- }
3281-
3282- private class StructFieldDecl extends StructOrTupleFieldDecl , TStructFieldDecl {
3283- private StructField sf ;
3284-
3285- StructFieldDecl ( ) { this = TStructFieldDecl ( sf ) }
3286-
3287- override AstNode getAstNode ( ) { result = sf }
3288-
3289- override TypeRepr getTypeRepr ( ) { result = sf .getTypeRepr ( ) }
3290- }
3291-
3292- private class TupleFieldDecl extends StructOrTupleFieldDecl , TTupleFieldDecl {
3293- private TupleField tf ;
3294-
3295- TupleFieldDecl ( ) { this = TTupleFieldDecl ( tf ) }
3296-
3297- override AstNode getAstNode ( ) { result = tf }
3298-
3299- override TypeRepr getTypeRepr ( ) { result = tf .getTypeRepr ( ) }
3300- }
3301-
3302- class AccessPosition = DeclarationPosition ;
3303-
3304- class Access extends FieldExpr {
3305- Type getTypeArgument ( TypeArgumentPosition apos , TypePath path ) { none ( ) }
3306-
3307- AstNode getNodeAt ( AccessPosition apos ) {
3308- result = this .getContainer ( ) and
3309- apos .isSelf ( )
3310- or
3311- result = this and
3312- apos .isField ( )
3313- }
3314-
3315- Type getInferredType ( AccessPosition apos , TypePath path ) {
3316- exists ( TypePath path0 | result = inferType ( this .getNodeAt ( apos ) , path0 ) |
3317- if apos .isSelf ( )
3318- then
3319- // adjust for implicit deref
3320- path0 .isCons ( getRefTypeParameter ( _) , path )
3321- or
3322- not path0 .isCons ( getRefTypeParameter ( _) , _) and
3323- not ( result instanceof RefType and path0 .isEmpty ( ) ) and
3324- path = path0
3325- else path = path0
3326- )
3327- }
3328-
3329- Declaration getTarget ( ) {
3330- // mutual recursion; resolving fields requires resolving types and vice versa
3331- result =
3332- [
3333- TStructFieldDecl ( resolveStructFieldExpr ( this , _) ) .( TDeclaration ) ,
3334- TTupleFieldDecl ( resolveTupleFieldExpr ( this , _) )
3335- ]
3336- }
3337- }
3338-
3339- predicate accessDeclarationPositionMatch ( AccessPosition apos , DeclarationPosition dpos ) {
3340- apos = dpos
3341- }
3342- }
3343-
3344- private module FieldExprMatching = Matching< FieldExprMatchingInput > ;
3345-
3346- /**
3347- * Gets the type of `n` at `path`, where `n` is either a field expression or
3348- * the receiver of field expression call.
3349- */
3350- pragma [ nomagic]
3351- private Type inferFieldExprType ( AstNode n , TypePath path , boolean topDown ) {
3352- exists (
3353- FieldExprMatchingInput:: Access a , FieldExprMatchingInput:: AccessPosition apos , TypePath path0
3354- |
3355- n = a .getNodeAt ( apos ) and
3356- result = FieldExprMatching:: inferAccessType ( a , apos , path0 )
3357- |
3358- if apos .isSelf ( )
3359- then
3360- topDown = true and
3361- exists ( Type receiverType | receiverType = inferType ( n ) |
3362- if receiverType instanceof RefType
3363- then
3364- // adjust for implicit deref
3365- not path0 .isCons ( getRefTypeParameter ( _) , _) and
3366- not ( path0 .isEmpty ( ) and result instanceof RefType ) and
3367- path = TypePath:: cons ( getRefTypeParameter ( _) , path0 )
3368- else path = path0
3369- )
3370- else (
3371- topDown = false and path = path0
3372- )
3373- )
3374- }
3375-
33763283/** Gets the root type of the reference expression `ref`. */
33773284pragma [ nomagic]
33783285private Type inferRefExprType ( RefExpr ref ) {
0 commit comments