@@ -278,6 +278,14 @@ private module Input3 implements InputSig3 {
278278
279279 class ParenExpr = Rust:: ParenExpr ;
280280
281+ final class Declaration = DeclarationImpl ;
282+
283+ abstract private class DeclarationImpl extends AstNode {
284+ abstract Type getDeclaringType ( TypePath path ) ;
285+
286+ abstract TypeMention getType ( ) ;
287+ }
288+
281289 private newtype TLocalVariable =
282290 TVariableVariable ( Rust:: Variable v ) or
283291 TConstVariable ( Const c ) or
@@ -316,14 +324,14 @@ private module Input3 implements InputSig3 {
316324 Location getLocation ( ) { result = this .getDefiningNode ( ) .getLocation ( ) }
317325 }
318326
319- abstract class LocalVariableDeclaration extends AstNode {
327+ abstract class LocalVariableDeclaration extends DeclarationImpl {
320328 abstract predicate isCoercionSite ( ) ;
321329
322- abstract TypeMention getType ( ) ;
323-
324330 abstract AstNode getPattern ( ) ;
325331
326332 abstract AstNode getInitializer ( ) ;
333+
334+ override Type getDeclaringType ( TypePath path ) { none ( ) }
327335 }
328336
329337 private class LetExprDeclaration extends LocalVariableDeclaration instanceof LetExpr {
@@ -354,6 +362,71 @@ private module Input3 implements InputSig3 {
354362 override AstNode getInitializer ( ) { result = LetStmt .super .getInitializer ( ) }
355363 }
356364
365+ abstract class Field extends DeclarationImpl {
366+ // no case for variants as those can only be destructured using pattern matching
367+ abstract Struct getStruct ( ) ;
368+
369+ override Type getDeclaringType ( TypePath path ) {
370+ exists ( Struct s | s = this .getStruct ( ) |
371+ result = TDataType ( s ) and
372+ path .isEmpty ( )
373+ or
374+ result = TTypeParamTypeParameter ( s .getGenericParamList ( ) .getATypeParam ( ) ) and
375+ path = TypePath:: singleton ( result )
376+ )
377+ }
378+ }
379+
380+ private class StructFieldDecl extends Field instanceof StructField {
381+ override Struct getStruct ( ) { this = result .getAStructField ( ) }
382+
383+ override TypeMention getType ( ) { result = StructField .super .getTypeRepr ( ) }
384+ }
385+
386+ private class TupleFieldDecl extends Field instanceof TupleField {
387+ override Struct getStruct ( ) { this = result .getATupleField ( ) }
388+
389+ override TypeMention getType ( ) { result = TupleField .super .getTypeRepr ( ) }
390+ }
391+
392+ class FieldAccess extends FieldExpr {
393+ Expr getReceiver ( ) { result = this .getContainer ( ) }
394+
395+ Field getField ( ) {
396+ // mutual recursion; resolving fields requires resolving types and vice versa
397+ result =
398+ [
399+ resolveStructFieldExpr ( this , _) .( AstNode ) ,
400+ resolveTupleFieldExpr ( this , _)
401+ ]
402+ }
403+ }
404+
405+ Type inferFieldAccessReceiverType ( FieldAccess fa , TypePath path ) {
406+ exists ( TypePath path0 | result = inferType ( fa .getReceiver ( ) , path0 ) |
407+ // adjust for implicit deref
408+ path0 .isCons ( getRefTypeParameter ( _) , path )
409+ or
410+ not path0 .isCons ( getRefTypeParameter ( _) , _) and
411+ not ( result instanceof RefType and path0 .isEmpty ( ) ) and
412+ path = path0
413+ )
414+ }
415+
416+ Type inferFieldAccessReceiverTypeContextual ( Expr receiver , TypePath path ) {
417+ exists ( TypePath path0 , Type receiverType |
418+ result = M3:: inferFieldAccessReceiverTypeContextualDefault ( _, receiver , path0 ) and
419+ receiverType = inferType ( receiver ) and
420+ not path0 .isEmpty ( )
421+ |
422+ // adjust for implicit deref
423+ path = TypePath:: cons ( receiverType .( RefType ) .getPositionalTypeParameter ( 0 ) , path0 )
424+ or
425+ not receiverType instanceof RefType and
426+ path = path0
427+ )
428+ }
429+
357430 final class Parameter = ParameterImpl ;
358431
359432 /** A parameter, including enum/struct constructor fields. */
@@ -389,19 +462,18 @@ private module Input3 implements InputSig3 {
389462
390463 final class Parameterizable = ParameterizableImpl ;
391464
392- abstract private class ParameterizableImpl extends AstNode {
465+ abstract private class ParameterizableImpl extends DeclarationImpl {
393466 abstract TypeParameter getTypeParameter ( int pos ) ;
394467
395468 abstract TypeMention getAdditionalTypeParameterConstraint ( TypeParameter tp ) ;
396469
397470 abstract TypeMention getDeclaringType ( ) ;
398471
399- // todo
400- Type getDeclaringType ( TypePath path ) { result = this .getDeclaringType ( ) .getTypeAt ( path ) }
472+ final override Type getDeclaringType ( TypePath path ) {
473+ result = this .getDeclaringType ( ) .getTypeAt ( path )
474+ }
401475
402476 abstract Parameter getParameter ( int i ) ;
403-
404- abstract TypeMention getType ( ) ;
405477 }
406478
407479 class Callable extends ParameterizableImpl instanceof Rust:: Callable {
@@ -470,19 +542,17 @@ private module Input3 implements InputSig3 {
470542 }
471543 }
472544
473- Type getParameterizableType ( Parameterizable p , TypePath path ) {
474- result = p .( Constructor ) .getType ( ) .getTypeAt ( path )
475- or
476- if p .( Function ) .isAsync ( ) or p .( ClosureExpr ) .isAsync ( )
545+ Type getCallableReturnType ( Callable c , TypePath path ) {
546+ if c .( Function ) .isAsync ( ) or c .( ClosureExpr ) .isAsync ( )
477547 then
478548 path .isEmpty ( ) and
479549 result = getFutureTraitType ( )
480550 or
481551 exists ( TypePath suffix |
482- result = getReturnTypeMention ( p ) .getTypeAt ( suffix ) and
552+ result = getReturnTypeMention ( c ) .getTypeAt ( suffix ) and
483553 path = TypePath:: cons ( getDynFutureOutputTypeParameter ( ) , suffix )
484554 )
485- else result = getReturnTypeMention ( p ) .getTypeAt ( path )
555+ else result = getReturnTypeMention ( c ) .getTypeAt ( path )
486556 }
487557
488558 class ResolutionContext = string ;
@@ -793,67 +863,6 @@ private module Input3 implements InputSig3 {
793863 )
794864 }
795865
796- abstract class Member extends AstNode {
797- Type getDeclaringType ( TypePath path ) {
798- // no case for variants as those can only be destructured using pattern matching
799- exists ( Struct s | this = [ s .getStructField ( _) .( AstNode ) , s .getTupleField ( _) ] |
800- result = TDataType ( s ) and
801- path .isEmpty ( )
802- or
803- result = TTypeParamTypeParameter ( s .getGenericParamList ( ) .getATypeParam ( ) ) and
804- path = TypePath:: singleton ( result )
805- )
806- }
807-
808- abstract TypeMention getType ( ) ;
809- }
810-
811- private class StructFieldDecl extends Member instanceof StructField {
812- override TypeMention getType ( ) { result = StructField .super .getTypeRepr ( ) }
813- }
814-
815- private class TupleFieldDecl extends Member instanceof TupleField {
816- override TypeMention getType ( ) { result = TupleField .super .getTypeRepr ( ) }
817- }
818-
819- class MemberAccess extends FieldExpr {
820- AstNode getReceiver ( ) { result = this .getContainer ( ) }
821-
822- Member getMember ( ) {
823- // mutual recursion; resolving fields requires resolving types and vice versa
824- result =
825- [
826- resolveStructFieldExpr ( this , _) .( AstNode ) ,
827- resolveTupleFieldExpr ( this , _)
828- ]
829- }
830- }
831-
832- Type inferMemberAccessReceiverType ( MemberAccess ma , TypePath path ) {
833- exists ( TypePath path0 | result = inferType ( ma .getReceiver ( ) , path0 ) |
834- // adjust for implicit deref
835- path0 .isCons ( getRefTypeParameter ( _) , path )
836- or
837- not path0 .isCons ( getRefTypeParameter ( _) , _) and
838- not ( result instanceof RefType and path0 .isEmpty ( ) ) and
839- path = path0
840- )
841- }
842-
843- Type inferMemberAccessReceiverTypeContextual ( AstNode n , TypePath path ) {
844- exists ( TypePath path0 , Type receiverType |
845- result = M3:: inferMemberAccessReceiverTypeContextualDefault ( _, n , path0 ) and
846- receiverType = inferType ( n ) and
847- not path0 .isEmpty ( )
848- |
849- // adjust for implicit deref
850- path = TypePath:: cons ( receiverType .( RefType ) .getPositionalTypeParameter ( 0 ) , path0 )
851- or
852- not receiverType instanceof RefType and
853- path = path0
854- )
855- }
856-
857866 class Closure extends Expr , Callable instanceof Rust:: ClosureExpr { }
858867
859868 class ClosureParameterPseudoType = T:: ClosureParameterPseudoType ;
@@ -3001,7 +3010,7 @@ private module DeconstructionPatMatchingInput implements MatchingInputSig {
30013010 result = this .getParameter ( pos .asPosition ( ) ) .getType ( ) .getTypeAt ( path )
30023011 or
30033012 pos .isReturn ( ) and
3004- result = Input3 :: getParameterizableType ( this , path )
3013+ result = this . getType ( ) . getTypeAt ( path )
30053014 }
30063015 }
30073016
0 commit comments