@@ -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 ) ) }
@@ -1524,20 +1524,22 @@ private predicate declares(ItemNode item, Namespace ns, string name) {
15241524 )
15251525}
15261526
1527- /** A path that does not access a local variable. */
1528- class RelevantPath extends Path {
1529- RelevantPath ( ) { not this = any ( VariableAccess va ) .( PathExpr ) .getPath ( ) }
1527+ /**
1528+ * A `Path` or an `IdentPat`.
1529+ *
1530+ * `IdentPat`s are included in order to resolve unqualified references
1531+ * to constructors in patterns.
1532+ */
1533+ abstract class PathExt extends AstNode {
1534+ abstract string getText ( ) ;
15301535
15311536 /** Holds if this is an unqualified path with the textual value `name`. */
15321537 pragma [ nomagic]
1533- predicate isUnqualified ( string name ) {
1534- not exists ( this .getQualifier ( ) ) and
1535- not exists ( UseTree tree |
1536- tree .hasPath ( ) and
1537- this = getAUseTreeUseTree ( tree ) .getPath ( ) .getQualifier * ( )
1538- ) and
1539- name = this .getText ( )
1540- }
1538+ abstract predicate isUnqualified ( string name ) ;
1539+
1540+ abstract Path getQualifier ( ) ;
1541+
1542+ abstract string toStringDebug ( ) ;
15411543
15421544 /**
15431545 * Holds if this is an unqualified path with the textual value `name` and
@@ -1559,6 +1561,33 @@ class RelevantPath extends Path {
15591561 predicate isDollarCrate ( ) { this .isUnqualified ( "$crate" , _) }
15601562}
15611563
1564+ private class PathExtPath extends PathExt instanceof Path {
1565+ override string getText ( ) { result = Path .super .getText ( ) }
1566+
1567+ override predicate isUnqualified ( string name ) {
1568+ not exists ( Path .super .getQualifier ( ) ) and
1569+ not exists ( UseTree tree |
1570+ tree .hasPath ( ) and
1571+ this = getAUseTreeUseTree ( tree ) .getPath ( ) .getQualifier * ( )
1572+ ) and
1573+ name = Path .super .getText ( )
1574+ }
1575+
1576+ override Path getQualifier ( ) { result = Path .super .getQualifier ( ) }
1577+
1578+ override string toStringDebug ( ) { result = Path .super .toStringDebug ( ) }
1579+ }
1580+
1581+ private class PathExtIdentPat extends PathExt , IdentPat {
1582+ override string getText ( ) { result = this .getName ( ) .getText ( ) }
1583+
1584+ override predicate isUnqualified ( string name ) { name = this .getText ( ) }
1585+
1586+ override Path getQualifier ( ) { none ( ) }
1587+
1588+ override string toStringDebug ( ) { result = this .getText ( ) }
1589+ }
1590+
15621591private predicate isModule ( ItemNode m ) { m instanceof Module }
15631592
15641593/** Holds if source file `source` contains the module `m`. */
@@ -1582,7 +1611,7 @@ private ItemNode getOuterScope(ItemNode i) {
15821611pragma [ nomagic]
15831612private predicate unqualifiedPathLookup ( ItemNode ancestor , string name , Namespace ns , ItemNode encl ) {
15841613 // lookup in the immediately enclosing item
1585- exists ( RelevantPath path |
1614+ exists ( PathExt path |
15861615 path .isUnqualified ( name , encl ) and
15871616 ancestor = encl and
15881617 not name = [ "crate" , "$crate" , "super" , "self" ]
@@ -1618,7 +1647,7 @@ private ItemNode getASuccessor(
16181647
16191648private predicate isSourceFile ( ItemNode source ) { source instanceof SourceFileItemNode }
16201649
1621- private predicate hasCratePath ( ItemNode i ) { any ( RelevantPath path ) .isCratePath ( _, i ) }
1650+ private predicate hasCratePath ( ItemNode i ) { any ( PathExt path ) .isCratePath ( _, i ) }
16221651
16231652private predicate hasChild ( ItemNode parent , ItemNode child ) { child .getImmediateParent ( ) = parent }
16241653
@@ -1630,7 +1659,7 @@ private predicate sourceFileHasCratePathTc(ItemNode i1, ItemNode i2) =
16301659 * `name` may be looked up inside `ancestor`.
16311660 */
16321661pragma [ nomagic]
1633- private predicate keywordLookup ( ItemNode ancestor , string name , RelevantPath p ) {
1662+ private predicate keywordLookup ( ItemNode ancestor , string name , PathExt p ) {
16341663 // For `crate`, jump directly to the root module
16351664 exists ( ItemNode i | p .isCratePath ( name , i ) |
16361665 ancestor instanceof SourceFile and
@@ -1644,7 +1673,7 @@ private predicate keywordLookup(ItemNode ancestor, string name, RelevantPath p)
16441673}
16451674
16461675pragma [ nomagic]
1647- private ItemNode unqualifiedPathLookup ( RelevantPath p , Namespace ns , SuccessorKind kind ) {
1676+ private ItemNode unqualifiedPathLookup ( PathExt p , Namespace ns , SuccessorKind kind ) {
16481677 exists ( ItemNode ancestor , string name |
16491678 result = getASuccessor ( ancestor , pragma [ only_bind_into ] ( name ) , ns , kind , _) and
16501679 kind .isInternalOrBoth ( )
@@ -1659,7 +1688,7 @@ private ItemNode unqualifiedPathLookup(RelevantPath p, Namespace ns, SuccessorKi
16591688}
16601689
16611690pragma [ nomagic]
1662- private predicate isUnqualifiedSelfPath ( RelevantPath path ) { path .isUnqualified ( "Self" ) }
1691+ private predicate isUnqualifiedSelfPath ( PathExt path ) { path .isUnqualified ( "Self" ) }
16631692
16641693/** Provides the input to `TraitIsVisible`. */
16651694signature predicate relevantTraitVisibleSig ( Element element , Trait trait ) ;
@@ -1742,14 +1771,14 @@ private module DollarCrateResolution {
17421771 isDollarCrateSupportedMacroExpansion ( _, expansion )
17431772 }
17441773
1745- private predicate isDollarCratePath ( RelevantPath p ) { p .isDollarCrate ( ) }
1774+ private predicate isDollarCratePath ( PathExt p ) { p .isDollarCrate ( ) }
17461775
1747- private predicate isInDollarCrateMacroExpansion ( RelevantPath p , AstNode expansion ) =
1776+ private predicate isInDollarCrateMacroExpansion ( PathExt p , AstNode expansion ) =
17481777 doublyBoundedFastTC( hasParent / 2 , isDollarCratePath / 1 , isDollarCrateSupportedMacroExpansion / 1 ) ( p ,
17491778 expansion )
17501779
17511780 pragma [ nomagic]
1752- private predicate isInDollarCrateMacroExpansionFromFile ( File macroDefFile , RelevantPath p ) {
1781+ private predicate isInDollarCrateMacroExpansionFromFile ( File macroDefFile , PathExt p ) {
17531782 exists ( Path macroDefPath , AstNode expansion |
17541783 isDollarCrateSupportedMacroExpansion ( macroDefPath , expansion ) and
17551784 isInDollarCrateMacroExpansion ( p , expansion ) and
@@ -1764,17 +1793,17 @@ private module DollarCrateResolution {
17641793 * calls.
17651794 */
17661795 pragma [ nomagic]
1767- predicate resolveDollarCrate ( RelevantPath p , CrateItemNode crate ) {
1796+ predicate resolveDollarCrate ( PathExt p , CrateItemNode crate ) {
17681797 isInDollarCrateMacroExpansionFromFile ( crate .getASourceFile ( ) .getFile ( ) , p )
17691798 }
17701799}
17711800
17721801pragma [ nomagic]
1773- private ItemNode resolvePathCand0 ( RelevantPath path , Namespace ns ) {
1802+ private ItemNode resolvePathCand0 ( PathExt path , Namespace ns ) {
17741803 exists ( ItemNode res |
17751804 res = unqualifiedPathLookup ( path , ns , _) and
17761805 if
1777- not any ( RelevantPath parent ) .getQualifier ( ) = path and
1806+ not any ( PathExt parent ) .getQualifier ( ) = path and
17781807 isUnqualifiedSelfPath ( path ) and
17791808 res instanceof ImplItemNode
17801809 then result = res .( ImplItemNodeImpl ) .resolveSelfTyCand ( )
@@ -1791,7 +1820,7 @@ private ItemNode resolvePathCand0(RelevantPath path, Namespace ns) {
17911820}
17921821
17931822pragma [ nomagic]
1794- private ItemNode resolvePathCandQualifier ( RelevantPath qualifier , RelevantPath path , string name ) {
1823+ private ItemNode resolvePathCandQualifier ( PathExt qualifier , PathExt path , string name ) {
17951824 qualifier = path .getQualifier ( ) and
17961825 result = resolvePathCand ( qualifier ) and
17971826 name = path .getText ( )
@@ -1839,9 +1868,7 @@ private predicate checkQualifiedVisibility(
18391868 * qualifier of `path` and `qualifier` resolves to `q`, if any.
18401869 */
18411870pragma [ nomagic]
1842- private ItemNode resolvePathCandQualified (
1843- RelevantPath qualifier , ItemNode q , RelevantPath path , Namespace ns
1844- ) {
1871+ private ItemNode resolvePathCandQualified ( PathExt qualifier , ItemNode q , PathExt path , Namespace ns ) {
18451872 exists ( string name , SuccessorKind kind , UseOption useOpt |
18461873 q = resolvePathCandQualifier ( qualifier , path , name ) and
18471874 result = getASuccessor ( q , name , ns , kind , useOpt ) and
@@ -1850,12 +1877,14 @@ private ItemNode resolvePathCandQualified(
18501877}
18511878
18521879/** Holds if path `p` must be looked up in namespace `n`. */
1853- private predicate pathUsesNamespace ( Path p , Namespace n ) {
1880+ private predicate pathUsesNamespace ( PathExt p , Namespace n ) {
18541881 n .isValue ( ) and
18551882 (
18561883 p = any ( PathExpr pe ) .getPath ( )
18571884 or
18581885 p = any ( TupleStructPat tsp ) .getPath ( )
1886+ or
1887+ p instanceof PathExtIdentPat
18591888 )
18601889 or
18611890 n .isType ( ) and
@@ -1931,7 +1960,7 @@ private predicate macroUseEdge(
19311960 * result in non-monotonic recursion.
19321961 */
19331962pragma [ nomagic]
1934- private ItemNode resolvePathCand ( RelevantPath path ) {
1963+ private ItemNode resolvePathCand ( PathExt path ) {
19351964 exists ( Namespace ns |
19361965 result = resolvePathCand0 ( path , ns ) and
19371966 if path = any ( ImplItemNode i ) .getSelfPath ( )
@@ -1944,7 +1973,10 @@ private ItemNode resolvePathCand(RelevantPath path) {
19441973 else
19451974 if path = any ( PathTypeRepr p ) .getPath ( )
19461975 then result instanceof TypeItemNode
1947- else any ( )
1976+ else
1977+ if path instanceof IdentPat
1978+ then result instanceof VariantItemNode or result instanceof StructItemNode
1979+ else any ( )
19481980 |
19491981 pathUsesNamespace ( path , ns )
19501982 or
@@ -1961,7 +1993,7 @@ private ItemNode resolvePathCand(RelevantPath path) {
19611993}
19621994
19631995/** Get a trait that should be visible when `path` resolves to `node`, if any. */
1964- private Trait getResolvePathTraitUsed ( RelevantPath path , AssocItemNode node ) {
1996+ private Trait getResolvePathTraitUsed ( PathExt path , AssocItemNode node ) {
19651997 exists ( TypeItemNode type , ImplItemNodeImpl impl |
19661998 node = resolvePathCandQualified ( _, type , path , _) and
19671999 typeImplEdge ( type , impl , _, _, node , _) and
@@ -1973,9 +2005,8 @@ private predicate pathTraitUsed(Element path, Trait trait) {
19732005 trait = getResolvePathTraitUsed ( path , _)
19742006}
19752007
1976- /** Gets the item that `path` resolves to, if any. */
19772008cached
1978- ItemNode resolvePath ( RelevantPath path ) {
2009+ private ItemNode resolvePath0 ( PathExt path ) {
19792010 result = resolvePathCand ( path ) and
19802011 not path = any ( Path parent | exists ( resolvePathCand ( parent ) ) ) .getQualifier ( ) and
19812012 (
@@ -1988,29 +2019,40 @@ ItemNode resolvePath(RelevantPath path) {
19882019 or
19892020 // if `path` is the qualifier of a resolvable `parent`, then we should
19902021 // resolve `path` to something consistent with what `parent` resolves to
1991- exists ( RelevantPath parent |
1992- resolvePathCandQualified ( path , result , parent , _) = resolvePath ( parent )
1993- )
2022+ exists ( PathExt parent | resolvePathCandQualified ( path , result , parent , _) = resolvePath0 ( parent ) )
19942023}
19952024
1996- private predicate isUseTreeSubPath ( UseTree tree , RelevantPath path ) {
2025+ /**
2026+ * Holds if `ip` resolves to some constructor.
2027+ */
2028+ // use `forceLocal` once we implement overlay support
2029+ predicate identPatIsResolvable ( IdentPat ip ) { exists ( resolvePath0 ( ip ) ) }
2030+
2031+ /** Gets the item that `path` resolves to, if any. */
2032+ pragma [ nomagic]
2033+ ItemNode resolvePath ( PathExt path ) {
2034+ result = resolvePath0 ( path ) and
2035+ not path = any ( VariableAccess va ) .( PathExpr ) .getPath ( )
2036+ }
2037+
2038+ private predicate isUseTreeSubPath ( UseTree tree , PathExt path ) {
19972039 path = tree .getPath ( )
19982040 or
1999- exists ( RelevantPath mid |
2041+ exists ( PathExt mid |
20002042 isUseTreeSubPath ( tree , mid ) and
20012043 path = mid .getQualifier ( )
20022044 )
20032045}
20042046
20052047pragma [ nomagic]
2006- private predicate isUseTreeSubPathUnqualified ( UseTree tree , RelevantPath path , string name ) {
2048+ private predicate isUseTreeSubPathUnqualified ( UseTree tree , PathExt path , string name ) {
20072049 isUseTreeSubPath ( tree , path ) and
20082050 not exists ( path .getQualifier ( ) ) and
20092051 name = path .getText ( )
20102052}
20112053
20122054pragma [ nomagic]
2013- private ItemNode resolveUseTreeListItem ( Use use , UseTree tree , RelevantPath path , SuccessorKind kind ) {
2055+ private ItemNode resolveUseTreeListItem ( Use use , UseTree tree , PathExt path , SuccessorKind kind ) {
20142056 exists ( UseOption useOpt | checkQualifiedVisibility ( use , result , kind , useOpt ) |
20152057 exists ( UseTree midTree , ItemNode mid , string name |
20162058 mid = resolveUseTreeListItem ( use , midTree ) and
@@ -2027,9 +2069,7 @@ private ItemNode resolveUseTreeListItem(Use use, UseTree tree, RelevantPath path
20272069}
20282070
20292071pragma [ nomagic]
2030- private ItemNode resolveUseTreeListItemQualifier (
2031- Use use , UseTree tree , RelevantPath path , string name
2032- ) {
2072+ private ItemNode resolveUseTreeListItemQualifier ( Use use , UseTree tree , PathExt path , string name ) {
20332073 result = resolveUseTreeListItem ( use , tree , path .getQualifier ( ) , _) and
20342074 name = path .getText ( )
20352075}
@@ -2178,12 +2218,12 @@ private module Debug {
21782218 exists ( string filepath , int startline , int startcolumn , int endline , int endcolumn |
21792219 result .getLocation ( ) .hasLocationInfo ( filepath , startline , startcolumn , endline , endcolumn ) and
21802220 filepath .matches ( "%/main.rs" ) and
2181- startline = 52
2221+ startline = 800
21822222 )
21832223 }
21842224
21852225 predicate debugUnqualifiedPathLookup (
2186- RelevantPath p , string name , Namespace ns , ItemNode ancestor , string path
2226+ PathExt p , string name , Namespace ns , ItemNode ancestor , string path
21872227 ) {
21882228 p = getRelevantLocatable ( ) and
21892229 exists ( ItemNode encl |
@@ -2195,12 +2235,12 @@ private module Debug {
21952235
21962236 predicate debugItemNode ( ItemNode item ) { item = getRelevantLocatable ( ) }
21972237
2198- ItemNode debugResolvePath ( RelevantPath path ) {
2238+ ItemNode debugResolvePath ( PathExt path ) {
21992239 path = getRelevantLocatable ( ) and
22002240 result = resolvePath ( path )
22012241 }
22022242
2203- ItemNode debugResolveUseTreeListItem ( Use use , UseTree tree , RelevantPath path , SuccessorKind kind ) {
2243+ ItemNode debugResolveUseTreeListItem ( Use use , UseTree tree , PathExt path , SuccessorKind kind ) {
22042244 use = getRelevantLocatable ( ) and
22052245 result = resolveUseTreeListItem ( use , tree , path , kind )
22062246 }
0 commit comments