@@ -864,41 +864,54 @@ class RelevantPath extends Path {
864
864
}
865
865
}
866
866
867
+ private predicate isModule ( ItemNode m ) { m instanceof Module }
868
+
869
+ /** Holds if root module `root` contains the module `m`. */
870
+ private predicate rootHasModule ( ItemNode root , ItemNode m ) =
871
+ doublyBoundedFastTC( hasChild / 2 , isRoot / 1 , isModule / 1 ) ( root , m )
872
+
873
+ pragma [ nomagic]
874
+ private ItemNode getOuterScope ( ItemNode i ) {
875
+ // nested modules do not have unqualified access to items from outer modules,
876
+ // except for items declared at top-level in the root module
877
+ rootHasModule ( result , i )
878
+ or
879
+ not i instanceof Module and
880
+ result = i .getImmediateParent ( )
881
+ }
882
+
883
+ pragma [ nomagic]
884
+ private ItemNode getAdjustedEnclosing ( ItemNode encl0 , Namespace ns ) {
885
+ // functions in `impl` blocks need to use explicit `Self::` to access other
886
+ // functions in the `impl` block
887
+ if encl0 instanceof ImplOrTraitItemNode and ns .isValue ( )
888
+ then result = encl0 .getImmediateParent ( )
889
+ else result = encl0
890
+ }
891
+
867
892
/**
868
893
* Holds if the unqualified path `p` references an item named `name`, and `name`
869
894
* may be looked up in the `ns` namespace inside enclosing item `encl`.
870
895
*/
871
896
pragma [ nomagic]
872
- private predicate unqualifiedPathLookup ( RelevantPath p , string name , Namespace ns , ItemNode encl ) {
873
- exists ( ItemNode encl0 |
897
+ private predicate unqualifiedPathLookup ( ItemNode encl , string name , Namespace ns , RelevantPath p ) {
898
+ exists ( ItemNode encl0 | encl = getAdjustedEnclosing ( encl0 , ns ) |
874
899
// lookup in the immediately enclosing item
875
900
p .isUnqualified ( name ) and
876
901
encl0 .getADescendant ( ) = p and
877
902
exists ( ns ) and
878
- not name = [ "crate" , "$crate" ]
903
+ not name = [ "crate" , "$crate" , "super" , "self" ]
879
904
or
880
905
// lookup in an outer scope, but only if the item is not declared in inner scope
881
906
exists ( ItemNode mid |
882
- unqualifiedPathLookup ( p , name , ns , mid ) and
907
+ unqualifiedPathLookup ( mid , name , ns , p ) and
883
908
not declares ( mid , ns , name ) and
884
- not name = [ "super" , "self" ] and
885
909
not (
886
910
name = "Self" and
887
911
mid = any ( ImplOrTraitItemNode i ) .getAnItemInSelfScope ( )
888
- )
889
- |
890
- // nested modules do not have unqualified access to items from outer modules,
891
- // except for items declared at top-level in the root module
892
- if mid instanceof Module
893
- then encl0 = mid .getImmediateParent + ( ) and encl0 .( ModuleLikeNode ) .isRoot ( )
894
- else encl0 = mid .getImmediateParent ( )
912
+ ) and
913
+ encl0 = getOuterScope ( mid )
895
914
)
896
- |
897
- // functions in `impl` blocks need to use explicit `Self::` to access other
898
- // functions in the `impl` block
899
- if encl0 instanceof ImplOrTraitItemNode and ns .isValue ( )
900
- then encl = encl0 .getImmediateParent ( )
901
- else encl = encl0
902
915
)
903
916
}
904
917
@@ -917,24 +930,34 @@ private predicate hasChild(ItemNode parent, ItemNode child) { child.getImmediate
917
930
private predicate rootHasCratePathTc ( ItemNode i1 , ItemNode i2 ) =
918
931
doublyBoundedFastTC( hasChild / 2 , isRoot / 1 , hasCratePath / 1 ) ( i1 , i2 )
919
932
933
+ /**
934
+ * Holds if the unqualified path `p` references a keyword item named `name`, and
935
+ * `name` may be looked up in the `ns` namespace inside enclosing item `encl`.
936
+ */
920
937
pragma [ nomagic]
921
- private predicate unqualifiedPathLookup1 ( RelevantPath p , string name , Namespace ns , ItemNode encl ) {
922
- unqualifiedPathLookup ( p , name , ns , encl )
923
- or
938
+ private predicate keywordLookup ( ItemNode encl , string name , Namespace ns , RelevantPath p ) {
924
939
// For `($)crate`, jump directly to the root module
925
940
exists ( ItemNode i | p .isCratePath ( name , i ) |
926
941
encl .( ModuleLikeNode ) .isRoot ( ) and
927
942
encl = i
928
943
or
929
944
rootHasCratePathTc ( encl , i )
930
945
)
946
+ or
947
+ name = [ "super" , "self" ] and
948
+ p .isUnqualified ( name ) and
949
+ exists ( ItemNode encl0 |
950
+ encl0 .getADescendant ( ) = p and
951
+ encl = getAdjustedEnclosing ( encl0 , ns )
952
+ )
931
953
}
932
954
933
955
pragma [ nomagic]
934
- private ItemNode unqualifiedPathLookup ( RelevantPath path , Namespace ns ) {
935
- exists ( ItemNode encl , string name |
936
- result = getASuccessor ( encl , name , ns ) and
937
- unqualifiedPathLookup1 ( path , name , ns , encl )
956
+ private ItemNode unqualifiedPathLookup ( RelevantPath p , Namespace ns ) {
957
+ exists ( ItemNode encl , string name | result = getASuccessor ( encl , name , ns ) |
958
+ unqualifiedPathLookup ( encl , name , ns , p )
959
+ or
960
+ keywordLookup ( encl , name , ns , p )
938
961
)
939
962
}
940
963
0 commit comments