@@ -856,41 +856,54 @@ class RelevantPath extends Path {
856856 }
857857}
858858
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+
859884/**
860885 * Holds if the unqualified path `p` references an item named `name`, and `name`
861886 * may be looked up in the `ns` namespace inside enclosing item `encl`.
862887 */
863888pragma [ 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 ) |
866891 // lookup in the immediately enclosing item
867892 p .isUnqualified ( name ) and
868893 encl0 .getADescendant ( ) = p and
869894 exists ( ns ) and
870- not name = [ "crate" , "$crate" ]
895+ not name = [ "crate" , "$crate" , "super" , "self" ]
871896 or
872897 // lookup in an outer scope, but only if the item is not declared in inner scope
873898 exists ( ItemNode mid |
874- unqualifiedPathLookup ( p , name , ns , mid ) and
899+ unqualifiedPathLookup ( mid , name , ns , p ) and
875900 not declares ( mid , ns , name ) and
876- not name = [ "super" , "self" ] and
877901 not (
878902 name = "Self" and
879903 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 )
887906 )
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
894907 )
895908}
896909
@@ -909,24 +922,34 @@ private predicate hasChild(ItemNode parent, ItemNode child) { child.getImmediate
909922private predicate rootHasCratePathTc ( ItemNode i1 , ItemNode i2 ) =
910923 doublyBoundedFastTC( hasChild / 2 , isRoot / 1 , hasCratePath / 1 ) ( i1 , i2 )
911924
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+ */
912929pragma [ 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 ) {
916931 // For `($)crate`, jump directly to the root module
917932 exists ( ItemNode i | p .isCratePath ( name , i ) |
918933 encl .( ModuleLikeNode ) .isRoot ( ) and
919934 encl = i
920935 or
921936 rootHasCratePathTc ( encl , i )
922937 )
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+ )
923945}
924946
925947pragma [ 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 )
930953 )
931954}
932955
0 commit comments