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