@@ -205,7 +205,7 @@ abstract class ItemNode extends Locatable {
205205 pragma [ nomagic]
206206 final Attr getAttr ( string name ) {
207207 result = this .getAnAttr ( ) and
208- result .getMeta ( ) .getPath ( ) .( RelevantPath ) .isUnqualified ( name )
208+ result .getMeta ( ) .getPath ( ) .( PathExt ) .isUnqualified ( name )
209209 }
210210
211211 final predicate hasAttr ( string name ) { exists ( this .getAttr ( name ) ) }
@@ -1503,17 +1503,22 @@ private predicate declares(ItemNode item, Namespace ns, string name) {
15031503 )
15041504}
15051505
1506- /** A path that does not access a local variable. */
1507- class RelevantPath extends Path {
1508- RelevantPath ( ) { not this = any ( VariableAccess va ) .( PathExpr ) .getPath ( ) }
1506+ /**
1507+ * A `Path` or an `IdentPat`.
1508+ *
1509+ * `IdentPat`s are included in order to resolve unqualified references
1510+ * to constructors in patterns.
1511+ */
1512+ abstract class PathExt extends AstNode {
1513+ abstract string getText ( ) ;
15091514
15101515 /** Holds if this is an unqualified path with the textual value `name`. */
15111516 pragma [ nomagic]
1512- predicate isUnqualified ( string name ) {
1513- not exists ( this . getQualifier ( ) ) and
1514- not this = any ( UseTreeList list ) . getAUseTree ( ) . getPath ( ) . getQualifier * ( ) and
1515- name = this . getText ( )
1516- }
1517+ abstract predicate isUnqualified ( string name ) ;
1518+
1519+ abstract Path getQualifier ( ) ;
1520+
1521+ abstract string toStringDebug ( ) ;
15171522
15181523 /**
15191524 * Holds if this is an unqualified path with the textual value `name` and
@@ -1535,6 +1540,30 @@ class RelevantPath extends Path {
15351540 predicate isDollarCrate ( ) { this .isUnqualified ( "$crate" , _) }
15361541}
15371542
1543+ private class PathExtPath extends PathExt instanceof Path {
1544+ override string getText ( ) { result = Path .super .getText ( ) }
1545+
1546+ override predicate isUnqualified ( string name ) {
1547+ not exists ( Path .super .getQualifier ( ) ) and
1548+ not this = any ( UseTreeList list ) .getAUseTree ( ) .getPath ( ) .getQualifier * ( ) and
1549+ name = Path .super .getText ( )
1550+ }
1551+
1552+ override Path getQualifier ( ) { result = Path .super .getQualifier ( ) }
1553+
1554+ override string toStringDebug ( ) { result = Path .super .toStringDebug ( ) }
1555+ }
1556+
1557+ private class PathExtIdentPat extends PathExt , IdentPat {
1558+ override string getText ( ) { result = this .getName ( ) .getText ( ) }
1559+
1560+ override predicate isUnqualified ( string name ) { name = this .getText ( ) }
1561+
1562+ override Path getQualifier ( ) { none ( ) }
1563+
1564+ override string toStringDebug ( ) { result = this .getText ( ) }
1565+ }
1566+
15381567private predicate isModule ( ItemNode m ) { m instanceof Module }
15391568
15401569/** Holds if source file `source` contains the module `m`. */
@@ -1558,7 +1587,7 @@ private ItemNode getOuterScope(ItemNode i) {
15581587pragma [ nomagic]
15591588private predicate unqualifiedPathLookup ( ItemNode ancestor , string name , Namespace ns , ItemNode encl ) {
15601589 // lookup in the immediately enclosing item
1561- exists ( RelevantPath path |
1590+ exists ( PathExt path |
15621591 path .isUnqualified ( name , encl ) and
15631592 ancestor = encl and
15641593 not name = [ "crate" , "$crate" , "super" , "self" ]
@@ -1594,7 +1623,7 @@ private ItemNode getASuccessor(
15941623
15951624private predicate isSourceFile ( ItemNode source ) { source instanceof SourceFileItemNode }
15961625
1597- private predicate hasCratePath ( ItemNode i ) { any ( RelevantPath path ) .isCratePath ( _, i ) }
1626+ private predicate hasCratePath ( ItemNode i ) { any ( PathExt path ) .isCratePath ( _, i ) }
15981627
15991628private predicate hasChild ( ItemNode parent , ItemNode child ) { child .getImmediateParent ( ) = parent }
16001629
@@ -1606,7 +1635,7 @@ private predicate sourceFileHasCratePathTc(ItemNode i1, ItemNode i2) =
16061635 * `name` may be looked up inside `ancestor`.
16071636 */
16081637pragma [ nomagic]
1609- private predicate keywordLookup ( ItemNode ancestor , string name , RelevantPath p ) {
1638+ private predicate keywordLookup ( ItemNode ancestor , string name , PathExt p ) {
16101639 // For `crate`, jump directly to the root module
16111640 exists ( ItemNode i | p .isCratePath ( name , i ) |
16121641 ancestor instanceof SourceFile and
@@ -1620,7 +1649,7 @@ private predicate keywordLookup(ItemNode ancestor, string name, RelevantPath p)
16201649}
16211650
16221651pragma [ nomagic]
1623- private ItemNode unqualifiedPathLookup ( RelevantPath p , Namespace ns , SuccessorKind kind ) {
1652+ private ItemNode unqualifiedPathLookup ( PathExt p , Namespace ns , SuccessorKind kind ) {
16241653 exists ( ItemNode ancestor , string name |
16251654 result = getASuccessor ( ancestor , pragma [ only_bind_into ] ( name ) , ns , kind , _) and
16261655 kind .isInternalOrBoth ( )
@@ -1635,7 +1664,7 @@ private ItemNode unqualifiedPathLookup(RelevantPath p, Namespace ns, SuccessorKi
16351664}
16361665
16371666pragma [ nomagic]
1638- private predicate isUnqualifiedSelfPath ( RelevantPath path ) { path .isUnqualified ( "Self" ) }
1667+ private predicate isUnqualifiedSelfPath ( PathExt path ) { path .isUnqualified ( "Self" ) }
16391668
16401669/** Provides the input to `TraitIsVisible`. */
16411670signature predicate relevantTraitVisibleSig ( Element element , Trait trait ) ;
@@ -1718,14 +1747,14 @@ private module DollarCrateResolution {
17181747 isDollarCrateSupportedMacroExpansion ( _, expansion )
17191748 }
17201749
1721- private predicate isDollarCratePath ( RelevantPath p ) { p .isDollarCrate ( ) }
1750+ private predicate isDollarCratePath ( PathExt p ) { p .isDollarCrate ( ) }
17221751
1723- private predicate isInDollarCrateMacroExpansion ( RelevantPath p , AstNode expansion ) =
1752+ private predicate isInDollarCrateMacroExpansion ( PathExt p , AstNode expansion ) =
17241753 doublyBoundedFastTC( hasParent / 2 , isDollarCratePath / 1 , isDollarCrateSupportedMacroExpansion / 1 ) ( p ,
17251754 expansion )
17261755
17271756 pragma [ nomagic]
1728- private predicate isInDollarCrateMacroExpansionFromFile ( File macroDefFile , RelevantPath p ) {
1757+ private predicate isInDollarCrateMacroExpansionFromFile ( File macroDefFile , PathExt p ) {
17291758 exists ( Path macroDefPath , AstNode expansion |
17301759 isDollarCrateSupportedMacroExpansion ( macroDefPath , expansion ) and
17311760 isInDollarCrateMacroExpansion ( p , expansion ) and
@@ -1740,17 +1769,17 @@ private module DollarCrateResolution {
17401769 * calls.
17411770 */
17421771 pragma [ nomagic]
1743- predicate resolveDollarCrate ( RelevantPath p , CrateItemNode crate ) {
1772+ predicate resolveDollarCrate ( PathExt p , CrateItemNode crate ) {
17441773 isInDollarCrateMacroExpansionFromFile ( crate .getASourceFile ( ) .getFile ( ) , p )
17451774 }
17461775}
17471776
17481777pragma [ nomagic]
1749- private ItemNode resolvePathCand0 ( RelevantPath path , Namespace ns ) {
1778+ private ItemNode resolvePathCand0 ( PathExt path , Namespace ns ) {
17501779 exists ( ItemNode res |
17511780 res = unqualifiedPathLookup ( path , ns , _) and
17521781 if
1753- not any ( RelevantPath parent ) .getQualifier ( ) = path and
1782+ not any ( PathExt parent ) .getQualifier ( ) = path and
17541783 isUnqualifiedSelfPath ( path ) and
17551784 res instanceof ImplItemNode
17561785 then result = res .( ImplItemNodeImpl ) .resolveSelfTyCand ( )
@@ -1767,7 +1796,7 @@ private ItemNode resolvePathCand0(RelevantPath path, Namespace ns) {
17671796}
17681797
17691798pragma [ nomagic]
1770- private ItemNode resolvePathCandQualifier ( RelevantPath qualifier , RelevantPath path , string name ) {
1799+ private ItemNode resolvePathCandQualifier ( PathExt qualifier , PathExt path , string name ) {
17711800 qualifier = path .getQualifier ( ) and
17721801 result = resolvePathCand ( qualifier ) and
17731802 name = path .getText ( )
@@ -1815,9 +1844,7 @@ private predicate checkQualifiedVisibility(
18151844 * qualifier of `path` and `qualifier` resolves to `q`, if any.
18161845 */
18171846pragma [ nomagic]
1818- private ItemNode resolvePathCandQualified (
1819- RelevantPath qualifier , ItemNode q , RelevantPath path , Namespace ns
1820- ) {
1847+ private ItemNode resolvePathCandQualified ( PathExt qualifier , ItemNode q , PathExt path , Namespace ns ) {
18211848 exists ( string name , SuccessorKind kind , UseOption useOpt |
18221849 q = resolvePathCandQualifier ( qualifier , path , name ) and
18231850 result = getASuccessor ( q , name , ns , kind , useOpt ) and
@@ -1826,12 +1853,14 @@ private ItemNode resolvePathCandQualified(
18261853}
18271854
18281855/** Holds if path `p` must be looked up in namespace `n`. */
1829- private predicate pathUsesNamespace ( Path p , Namespace n ) {
1856+ private predicate pathUsesNamespace ( PathExt p , Namespace n ) {
18301857 n .isValue ( ) and
18311858 (
18321859 p = any ( PathExpr pe ) .getPath ( )
18331860 or
18341861 p = any ( TupleStructPat tsp ) .getPath ( )
1862+ or
1863+ p instanceof PathExtIdentPat
18351864 )
18361865 or
18371866 n .isType ( ) and
@@ -1907,7 +1936,7 @@ private predicate macroUseEdge(
19071936 * result in non-monotonic recursion.
19081937 */
19091938pragma [ nomagic]
1910- private ItemNode resolvePathCand ( RelevantPath path ) {
1939+ private ItemNode resolvePathCand ( PathExt path ) {
19111940 exists ( Namespace ns |
19121941 result = resolvePathCand0 ( path , ns ) and
19131942 if path = any ( ImplItemNode i ) .getSelfPath ( )
@@ -1920,7 +1949,10 @@ private ItemNode resolvePathCand(RelevantPath path) {
19201949 else
19211950 if path = any ( PathTypeRepr p ) .getPath ( )
19221951 then result instanceof TypeItemNode
1923- else any ( )
1952+ else
1953+ if path instanceof IdentPat
1954+ then result instanceof VariantItemNode or result instanceof StructItemNode
1955+ else any ( )
19241956 |
19251957 pathUsesNamespace ( path , ns )
19261958 or
@@ -1937,7 +1969,7 @@ private ItemNode resolvePathCand(RelevantPath path) {
19371969}
19381970
19391971/** Get a trait that should be visible when `path` resolves to `node`, if any. */
1940- private Trait getResolvePathTraitUsed ( RelevantPath path , AssocItemNode node ) {
1972+ private Trait getResolvePathTraitUsed ( PathExt path , AssocItemNode node ) {
19411973 exists ( TypeItemNode type , ImplItemNodeImpl impl |
19421974 node = resolvePathCandQualified ( _, type , path , _) and
19431975 typeImplEdge ( type , impl , _, _, node , _) and
@@ -1951,7 +1983,7 @@ private predicate pathTraitUsed(Element path, Trait trait) {
19511983
19521984/** Gets the item that `path` resolves to, if any. */
19531985cached
1954- ItemNode resolvePath ( RelevantPath path ) {
1986+ private ItemNode resolvePath0 ( PathExt path ) {
19551987 result = resolvePathCand ( path ) and
19561988 not path = any ( Path parent | exists ( resolvePathCand ( parent ) ) ) .getQualifier ( ) and
19571989 (
@@ -1964,29 +1996,40 @@ ItemNode resolvePath(RelevantPath path) {
19641996 or
19651997 // if `path` is the qualifier of a resolvable `parent`, then we should
19661998 // resolve `path` to something consistent with what `parent` resolves to
1967- exists ( RelevantPath parent |
1968- resolvePathCandQualified ( path , result , parent , _) = resolvePath ( parent )
1969- )
1999+ exists ( PathExt parent | resolvePathCandQualified ( path , result , parent , _) = resolvePath0 ( parent ) )
19702000}
19712001
1972- private predicate isUseTreeSubPath ( UseTree tree , RelevantPath path ) {
2002+ /** Gets the item that `path` resolves to, if any. */
2003+ pragma [ nomagic]
2004+ ItemNode resolvePath ( PathExt path ) {
2005+ result = resolvePath0 ( path ) and
2006+ not path = any ( VariableAccess va ) .( PathExpr ) .getPath ( )
2007+ }
2008+
2009+ /**
2010+ * Holds if `ip` resolves to some constructor.
2011+ */
2012+ // use `forceLocal` once we implement overlay support
2013+ predicate identPatIsResolvable ( IdentPat ip ) { exists ( resolvePath0 ( ip ) ) }
2014+
2015+ private predicate isUseTreeSubPath ( UseTree tree , PathExt path ) {
19732016 path = tree .getPath ( )
19742017 or
1975- exists ( RelevantPath mid |
2018+ exists ( PathExt mid |
19762019 isUseTreeSubPath ( tree , mid ) and
19772020 path = mid .getQualifier ( )
19782021 )
19792022}
19802023
19812024pragma [ nomagic]
1982- private predicate isUseTreeSubPathUnqualified ( UseTree tree , RelevantPath path , string name ) {
2025+ private predicate isUseTreeSubPathUnqualified ( UseTree tree , PathExt path , string name ) {
19832026 isUseTreeSubPath ( tree , path ) and
19842027 not exists ( path .getQualifier ( ) ) and
19852028 name = path .getText ( )
19862029}
19872030
19882031pragma [ nomagic]
1989- private ItemNode resolveUseTreeListItem ( Use use , UseTree tree , RelevantPath path , SuccessorKind kind ) {
2032+ private ItemNode resolveUseTreeListItem ( Use use , UseTree tree , PathExt path , SuccessorKind kind ) {
19902033 exists ( UseOption useOpt | checkQualifiedVisibility ( use , result , kind , useOpt ) |
19912034 exists ( UseTree midTree , ItemNode mid , string name |
19922035 mid = resolveUseTreeListItem ( use , midTree ) and
@@ -2003,9 +2046,7 @@ private ItemNode resolveUseTreeListItem(Use use, UseTree tree, RelevantPath path
20032046}
20042047
20052048pragma [ nomagic]
2006- private ItemNode resolveUseTreeListItemQualifier (
2007- Use use , UseTree tree , RelevantPath path , string name
2008- ) {
2049+ private ItemNode resolveUseTreeListItemQualifier ( Use use , UseTree tree , PathExt path , string name ) {
20092050 result = resolveUseTreeListItem ( use , tree , path .getQualifier ( ) , _) and
20102051 name = path .getText ( )
20112052}
@@ -2137,12 +2178,12 @@ private module Debug {
21372178 exists ( string filepath , int startline , int startcolumn , int endline , int endcolumn |
21382179 result .getLocation ( ) .hasLocationInfo ( filepath , startline , startcolumn , endline , endcolumn ) and
21392180 filepath .matches ( "%/main.rs" ) and
2140- startline = 52
2181+ startline = 800
21412182 )
21422183 }
21432184
21442185 predicate debugUnqualifiedPathLookup (
2145- RelevantPath p , string name , Namespace ns , ItemNode ancestor , string path
2186+ PathExt p , string name , Namespace ns , ItemNode ancestor , string path
21462187 ) {
21472188 p = getRelevantLocatable ( ) and
21482189 exists ( ItemNode encl |
@@ -2154,7 +2195,7 @@ private module Debug {
21542195
21552196 predicate debugItemNode ( ItemNode item ) { item = getRelevantLocatable ( ) }
21562197
2157- ItemNode debugResolvePath ( RelevantPath path ) {
2198+ ItemNode debugResolvePath ( PathExt path ) {
21582199 path = getRelevantLocatable ( ) and
21592200 result = resolvePath ( path )
21602201 }
0 commit comments