@@ -864,41 +864,54 @@ class RelevantPath extends Path {
864864 }
865865}
866866
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+
867892/**
868893 * Holds if the unqualified path `p` references an item named `name`, and `name`
869894 * may be looked up in the `ns` namespace inside enclosing item `encl`.
870895 */
871896pragma [ 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 ) |
874899 // lookup in the immediately enclosing item
875900 p .isUnqualified ( name ) and
876901 encl0 .getADescendant ( ) = p and
877902 exists ( ns ) and
878- not name = [ "crate" , "$crate" ]
903+ not name = [ "crate" , "$crate" , "super" , "self" ]
879904 or
880905 // lookup in an outer scope, but only if the item is not declared in inner scope
881906 exists ( ItemNode mid |
882- unqualifiedPathLookup ( p , name , ns , mid ) and
907+ unqualifiedPathLookup ( mid , name , ns , p ) and
883908 not declares ( mid , ns , name ) and
884- not name = [ "super" , "self" ] and
885909 not (
886910 name = "Self" and
887911 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 )
895914 )
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
902915 )
903916}
904917
@@ -917,24 +930,34 @@ private predicate hasChild(ItemNode parent, ItemNode child) { child.getImmediate
917930private predicate rootHasCratePathTc ( ItemNode i1 , ItemNode i2 ) =
918931 doublyBoundedFastTC( hasChild / 2 , isRoot / 1 , hasCratePath / 1 ) ( i1 , i2 )
919932
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+ */
920937pragma [ 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 ) {
924939 // For `($)crate`, jump directly to the root module
925940 exists ( ItemNode i | p .isCratePath ( name , i ) |
926941 encl .( ModuleLikeNode ) .isRoot ( ) and
927942 encl = i
928943 or
929944 rootHasCratePathTc ( encl , i )
930945 )
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+ )
931953}
932954
933955pragma [ 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 )
938961 )
939962}
940963
0 commit comments