@@ -651,7 +651,7 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
651
651
*
652
652
* class Sub<T4> : Mid<C<T4>> { }
653
653
*
654
- * new Sub<int>().Method();
654
+ * new Sub<int>().Method(); // Note: `Sub<int>` is a subtype of `Base<C<C<int>>>`
655
655
* // ^^^^^^^^^^^^^^^^^^^^^^^ `a`
656
656
* ```
657
657
*
@@ -675,6 +675,11 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
675
675
)
676
676
}
677
677
678
+ /**
679
+ * Holds if for `a` and corresponding `target`, the type parameter `tp` is
680
+ * matched by a type argument at the access with type `t` and type path
681
+ * `path`.
682
+ */
678
683
pragma [ nomagic]
679
684
private predicate explicitTypeMatch (
680
685
Access a , Declaration target , TypePath path , Type t , TypeParameter tp
@@ -687,17 +692,23 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
687
692
private predicate implicitTypeMatch (
688
693
Access a , Declaration target , TypePath path , Type t , TypeParameter tp
689
694
) {
695
+ // We can get the type of `tp` from one of the access positions
690
696
directTypeMatch ( a , target , path , t , tp )
691
697
or
698
+ // We can get the type of `tp` by going up the type hiearchy
692
699
baseTypeMatch ( a , target , path , t , tp )
693
700
}
694
701
695
702
pragma [ inline]
696
703
private predicate typeMatch (
697
704
Access a , Declaration target , TypePath path , Type t , TypeParameter tp
698
705
) {
706
+ // A type given at the access corresponds directly to the type parameter
707
+ // at the target.
699
708
explicitTypeMatch ( a , target , path , t , tp )
700
709
or
710
+ // No explicit type argument, so we deduce the parameter from other
711
+ // information
701
712
implicitTypeMatch ( a , target , path , t , tp )
702
713
}
703
714
@@ -742,12 +753,14 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
742
753
pragma [ nomagic]
743
754
Type inferAccessType ( Access a , AccessPosition apos , TypePath path ) {
744
755
exists ( DeclarationPosition dpos | accessDeclarationPositionMatch ( apos , dpos ) |
756
+ // A suffix of `path` leads to a type parameter in the target
745
757
exists ( Declaration target , TypePath prefix , TypeParameter tp , TypePath suffix |
746
758
tp = target .getDeclaredType ( pragma [ only_bind_into ] ( dpos ) , prefix ) and
747
759
path = prefix .append ( suffix ) and
748
760
typeMatch ( a , target , suffix , result , tp )
749
761
)
750
762
or
763
+ // `path` corresponds directly to a concrete type in the declaration
751
764
exists ( Declaration target |
752
765
result = target .getDeclaredType ( pragma [ only_bind_into ] ( dpos ) , path ) and
753
766
target = a .getTarget ( ) and
0 commit comments