@@ -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