@@ -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 ) ) }
@@ -1521,20 +1521,22 @@ private predicate declares(ItemNode item, Namespace ns, string name) {
15211521 )
15221522}
15231523
1524- /** A path that does not access a local variable. */
1525- class RelevantPath extends Path {
1526- RelevantPath ( ) { not this = any ( VariableAccess va ) .( PathExpr ) .getPath ( ) }
1524+ /**
1525+ * A `Path` or an `IdentPat`.
1526+ *
1527+ * `IdentPat`s are included in order to resolve unqualified references
1528+ * to constructors in patterns.
1529+ */
1530+ abstract class PathExt extends AstNode {
1531+ abstract string getText ( ) ;
15271532
15281533 /** Holds if this is an unqualified path with the textual value `name`. */
15291534 pragma [ nomagic]
1530- predicate isUnqualified ( string name ) {
1531- not exists ( this .getQualifier ( ) ) and
1532- not exists ( UseTree tree |
1533- tree .hasPath ( ) and
1534- this = getAUseTreeUseTree ( tree ) .getPath ( ) .getQualifier * ( )
1535- ) and
1536- name = this .getText ( )
1537- }
1535+ abstract predicate isUnqualified ( string name ) ;
1536+
1537+ abstract Path getQualifier ( ) ;
1538+
1539+ abstract string toStringDebug ( ) ;
15381540
15391541 /**
15401542 * Holds if this is an unqualified path with the textual value `name` and
@@ -1556,6 +1558,33 @@ class RelevantPath extends Path {
15561558 predicate isDollarCrate ( ) { this .isUnqualified ( "$crate" , _) }
15571559}
15581560
1561+ private class PathExtPath extends PathExt instanceof Path {
1562+ override string getText ( ) { result = Path .super .getText ( ) }
1563+
1564+ override predicate isUnqualified ( string name ) {
1565+ not exists ( Path .super .getQualifier ( ) ) and
1566+ not exists ( UseTree tree |
1567+ tree .hasPath ( ) and
1568+ this = getAUseTreeUseTree ( tree ) .getPath ( ) .getQualifier * ( )
1569+ ) and
1570+ name = Path .super .getText ( )
1571+ }
1572+
1573+ override Path getQualifier ( ) { result = Path .super .getQualifier ( ) }
1574+
1575+ override string toStringDebug ( ) { result = Path .super .toStringDebug ( ) }
1576+ }
1577+
1578+ private class PathExtIdentPat extends PathExt , IdentPat {
1579+ override string getText ( ) { result = this .getName ( ) .getText ( ) }
1580+
1581+ override predicate isUnqualified ( string name ) { name = this .getText ( ) }
1582+
1583+ override Path getQualifier ( ) { none ( ) }
1584+
1585+ override string toStringDebug ( ) { result = this .getText ( ) }
1586+ }
1587+
15591588private predicate isModule ( ItemNode m ) { m instanceof Module }
15601589
15611590/** Holds if source file `source` contains the module `m`. */
@@ -1579,7 +1608,7 @@ private ItemNode getOuterScope(ItemNode i) {
15791608pragma [ nomagic]
15801609private predicate unqualifiedPathLookup ( ItemNode ancestor , string name , Namespace ns , ItemNode encl ) {
15811610 // lookup in the immediately enclosing item
1582- exists ( RelevantPath path |
1611+ exists ( PathExt path |
15831612 path .isUnqualified ( name , encl ) and
15841613 ancestor = encl and
15851614 not name = [ "crate" , "$crate" , "super" , "self" ]
@@ -1615,7 +1644,7 @@ private ItemNode getASuccessor(
16151644
16161645private predicate isSourceFile ( ItemNode source ) { source instanceof SourceFileItemNode }
16171646
1618- private predicate hasCratePath ( ItemNode i ) { any ( RelevantPath path ) .isCratePath ( _, i ) }
1647+ private predicate hasCratePath ( ItemNode i ) { any ( PathExt path ) .isCratePath ( _, i ) }
16191648
16201649private predicate hasChild ( ItemNode parent , ItemNode child ) { child .getImmediateParent ( ) = parent }
16211650
@@ -1627,7 +1656,7 @@ private predicate sourceFileHasCratePathTc(ItemNode i1, ItemNode i2) =
16271656 * `name` may be looked up inside `ancestor`.
16281657 */
16291658pragma [ nomagic]
1630- private predicate keywordLookup ( ItemNode ancestor , string name , RelevantPath p ) {
1659+ private predicate keywordLookup ( ItemNode ancestor , string name , PathExt p ) {
16311660 // For `crate`, jump directly to the root module
16321661 exists ( ItemNode i | p .isCratePath ( name , i ) |
16331662 ancestor instanceof SourceFile and
@@ -1641,7 +1670,7 @@ private predicate keywordLookup(ItemNode ancestor, string name, RelevantPath p)
16411670}
16421671
16431672pragma [ nomagic]
1644- private ItemNode unqualifiedPathLookup ( RelevantPath p , Namespace ns , SuccessorKind kind ) {
1673+ private ItemNode unqualifiedPathLookup ( PathExt p , Namespace ns , SuccessorKind kind ) {
16451674 exists ( ItemNode ancestor , string name |
16461675 result = getASuccessor ( ancestor , pragma [ only_bind_into ] ( name ) , ns , kind , _) and
16471676 kind .isInternalOrBoth ( )
@@ -1656,7 +1685,7 @@ private ItemNode unqualifiedPathLookup(RelevantPath p, Namespace ns, SuccessorKi
16561685}
16571686
16581687pragma [ nomagic]
1659- private predicate isUnqualifiedSelfPath ( RelevantPath path ) { path .isUnqualified ( "Self" ) }
1688+ private predicate isUnqualifiedSelfPath ( PathExt path ) { path .isUnqualified ( "Self" ) }
16601689
16611690/** Provides the input to `TraitIsVisible`. */
16621691signature predicate relevantTraitVisibleSig ( Element element , Trait trait ) ;
@@ -1739,14 +1768,14 @@ private module DollarCrateResolution {
17391768 isDollarCrateSupportedMacroExpansion ( _, expansion )
17401769 }
17411770
1742- private predicate isDollarCratePath ( RelevantPath p ) { p .isDollarCrate ( ) }
1771+ private predicate isDollarCratePath ( PathExt p ) { p .isDollarCrate ( ) }
17431772
1744- private predicate isInDollarCrateMacroExpansion ( RelevantPath p , AstNode expansion ) =
1773+ private predicate isInDollarCrateMacroExpansion ( PathExt p , AstNode expansion ) =
17451774 doublyBoundedFastTC( hasParent / 2 , isDollarCratePath / 1 , isDollarCrateSupportedMacroExpansion / 1 ) ( p ,
17461775 expansion )
17471776
17481777 pragma [ nomagic]
1749- private predicate isInDollarCrateMacroExpansionFromFile ( File macroDefFile , RelevantPath p ) {
1778+ private predicate isInDollarCrateMacroExpansionFromFile ( File macroDefFile , PathExt p ) {
17501779 exists ( Path macroDefPath , AstNode expansion |
17511780 isDollarCrateSupportedMacroExpansion ( macroDefPath , expansion ) and
17521781 isInDollarCrateMacroExpansion ( p , expansion ) and
@@ -1761,17 +1790,17 @@ private module DollarCrateResolution {
17611790 * calls.
17621791 */
17631792 pragma [ nomagic]
1764- predicate resolveDollarCrate ( RelevantPath p , CrateItemNode crate ) {
1793+ predicate resolveDollarCrate ( PathExt p , CrateItemNode crate ) {
17651794 isInDollarCrateMacroExpansionFromFile ( crate .getASourceFile ( ) .getFile ( ) , p )
17661795 }
17671796}
17681797
17691798pragma [ nomagic]
1770- private ItemNode resolvePathCand0 ( RelevantPath path , Namespace ns ) {
1799+ private ItemNode resolvePathCand0 ( PathExt path , Namespace ns ) {
17711800 exists ( ItemNode res |
17721801 res = unqualifiedPathLookup ( path , ns , _) and
17731802 if
1774- not any ( RelevantPath parent ) .getQualifier ( ) = path and
1803+ not any ( PathExt parent ) .getQualifier ( ) = path and
17751804 isUnqualifiedSelfPath ( path ) and
17761805 res instanceof ImplItemNode
17771806 then result = res .( ImplItemNodeImpl ) .resolveSelfTyCand ( )
@@ -1788,7 +1817,7 @@ private ItemNode resolvePathCand0(RelevantPath path, Namespace ns) {
17881817}
17891818
17901819pragma [ nomagic]
1791- private ItemNode resolvePathCandQualifier ( RelevantPath qualifier , RelevantPath path , string name ) {
1820+ private ItemNode resolvePathCandQualifier ( PathExt qualifier , PathExt path , string name ) {
17921821 qualifier = path .getQualifier ( ) and
17931822 result = resolvePathCand ( qualifier ) and
17941823 name = path .getText ( )
@@ -1836,9 +1865,7 @@ private predicate checkQualifiedVisibility(
18361865 * qualifier of `path` and `qualifier` resolves to `q`, if any.
18371866 */
18381867pragma [ nomagic]
1839- private ItemNode resolvePathCandQualified (
1840- RelevantPath qualifier , ItemNode q , RelevantPath path , Namespace ns
1841- ) {
1868+ private ItemNode resolvePathCandQualified ( PathExt qualifier , ItemNode q , PathExt path , Namespace ns ) {
18421869 exists ( string name , SuccessorKind kind , UseOption useOpt |
18431870 q = resolvePathCandQualifier ( qualifier , path , name ) and
18441871 result = getASuccessor ( q , name , ns , kind , useOpt ) and
@@ -1847,12 +1874,14 @@ private ItemNode resolvePathCandQualified(
18471874}
18481875
18491876/** Holds if path `p` must be looked up in namespace `n`. */
1850- private predicate pathUsesNamespace ( Path p , Namespace n ) {
1877+ private predicate pathUsesNamespace ( PathExt p , Namespace n ) {
18511878 n .isValue ( ) and
18521879 (
18531880 p = any ( PathExpr pe ) .getPath ( )
18541881 or
18551882 p = any ( TupleStructPat tsp ) .getPath ( )
1883+ or
1884+ p instanceof PathExtIdentPat
18561885 )
18571886 or
18581887 n .isType ( ) and
@@ -1928,7 +1957,7 @@ private predicate macroUseEdge(
19281957 * result in non-monotonic recursion.
19291958 */
19301959pragma [ nomagic]
1931- private ItemNode resolvePathCand ( RelevantPath path ) {
1960+ private ItemNode resolvePathCand ( PathExt path ) {
19321961 exists ( Namespace ns |
19331962 result = resolvePathCand0 ( path , ns ) and
19341963 if path = any ( ImplItemNode i ) .getSelfPath ( )
@@ -1941,7 +1970,10 @@ private ItemNode resolvePathCand(RelevantPath path) {
19411970 else
19421971 if path = any ( PathTypeRepr p ) .getPath ( )
19431972 then result instanceof TypeItemNode
1944- else any ( )
1973+ else
1974+ if path instanceof IdentPat
1975+ then result instanceof VariantItemNode or result instanceof StructItemNode
1976+ else any ( )
19451977 |
19461978 pathUsesNamespace ( path , ns )
19471979 or
@@ -1958,7 +1990,7 @@ private ItemNode resolvePathCand(RelevantPath path) {
19581990}
19591991
19601992/** Get a trait that should be visible when `path` resolves to `node`, if any. */
1961- private Trait getResolvePathTraitUsed ( RelevantPath path , AssocItemNode node ) {
1993+ private Trait getResolvePathTraitUsed ( PathExt path , AssocItemNode node ) {
19621994 exists ( TypeItemNode type , ImplItemNodeImpl impl |
19631995 node = resolvePathCandQualified ( _, type , path , _) and
19641996 typeImplEdge ( type , impl , _, _, node , _) and
@@ -1970,9 +2002,8 @@ private predicate pathTraitUsed(Element path, Trait trait) {
19702002 trait = getResolvePathTraitUsed ( path , _)
19712003}
19722004
1973- /** Gets the item that `path` resolves to, if any. */
19742005cached
1975- ItemNode resolvePath ( RelevantPath path ) {
2006+ private ItemNode resolvePath0 ( PathExt path ) {
19762007 result = resolvePathCand ( path ) and
19772008 not path = any ( Path parent | exists ( resolvePathCand ( parent ) ) ) .getQualifier ( ) and
19782009 (
@@ -1985,29 +2016,40 @@ ItemNode resolvePath(RelevantPath path) {
19852016 or
19862017 // if `path` is the qualifier of a resolvable `parent`, then we should
19872018 // resolve `path` to something consistent with what `parent` resolves to
1988- exists ( RelevantPath parent |
1989- resolvePathCandQualified ( path , result , parent , _) = resolvePath ( parent )
1990- )
2019+ exists ( PathExt parent | resolvePathCandQualified ( path , result , parent , _) = resolvePath0 ( parent ) )
19912020}
19922021
1993- private predicate isUseTreeSubPath ( UseTree tree , RelevantPath path ) {
2022+ /**
2023+ * Holds if `ip` resolves to some constructor.
2024+ */
2025+ // use `forceLocal` once we implement overlay support
2026+ predicate identPatIsResolvable ( IdentPat ip ) { exists ( resolvePath0 ( ip ) ) }
2027+
2028+ /** Gets the item that `path` resolves to, if any. */
2029+ pragma [ nomagic]
2030+ ItemNode resolvePath ( PathExt path ) {
2031+ result = resolvePath0 ( path ) and
2032+ not path = any ( VariableAccess va ) .( PathExpr ) .getPath ( )
2033+ }
2034+
2035+ private predicate isUseTreeSubPath ( UseTree tree , PathExt path ) {
19942036 path = tree .getPath ( )
19952037 or
1996- exists ( RelevantPath mid |
2038+ exists ( PathExt mid |
19972039 isUseTreeSubPath ( tree , mid ) and
19982040 path = mid .getQualifier ( )
19992041 )
20002042}
20012043
20022044pragma [ nomagic]
2003- private predicate isUseTreeSubPathUnqualified ( UseTree tree , RelevantPath path , string name ) {
2045+ private predicate isUseTreeSubPathUnqualified ( UseTree tree , PathExt path , string name ) {
20042046 isUseTreeSubPath ( tree , path ) and
20052047 not exists ( path .getQualifier ( ) ) and
20062048 name = path .getText ( )
20072049}
20082050
20092051pragma [ nomagic]
2010- private ItemNode resolveUseTreeListItem ( Use use , UseTree tree , RelevantPath path , SuccessorKind kind ) {
2052+ private ItemNode resolveUseTreeListItem ( Use use , UseTree tree , PathExt path , SuccessorKind kind ) {
20112053 exists ( UseOption useOpt | checkQualifiedVisibility ( use , result , kind , useOpt ) |
20122054 exists ( UseTree midTree , ItemNode mid , string name |
20132055 mid = resolveUseTreeListItem ( use , midTree ) and
@@ -2024,9 +2066,7 @@ private ItemNode resolveUseTreeListItem(Use use, UseTree tree, RelevantPath path
20242066}
20252067
20262068pragma [ nomagic]
2027- private ItemNode resolveUseTreeListItemQualifier (
2028- Use use , UseTree tree , RelevantPath path , string name
2029- ) {
2069+ private ItemNode resolveUseTreeListItemQualifier ( Use use , UseTree tree , PathExt path , string name ) {
20302070 result = resolveUseTreeListItem ( use , tree , path .getQualifier ( ) , _) and
20312071 name = path .getText ( )
20322072}
@@ -2175,12 +2215,12 @@ private module Debug {
21752215 exists ( string filepath , int startline , int startcolumn , int endline , int endcolumn |
21762216 result .getLocation ( ) .hasLocationInfo ( filepath , startline , startcolumn , endline , endcolumn ) and
21772217 filepath .matches ( "%/main.rs" ) and
2178- startline = 52
2218+ startline = 800
21792219 )
21802220 }
21812221
21822222 predicate debugUnqualifiedPathLookup (
2183- RelevantPath p , string name , Namespace ns , ItemNode ancestor , string path
2223+ PathExt p , string name , Namespace ns , ItemNode ancestor , string path
21842224 ) {
21852225 p = getRelevantLocatable ( ) and
21862226 exists ( ItemNode encl |
@@ -2192,12 +2232,12 @@ private module Debug {
21922232
21932233 predicate debugItemNode ( ItemNode item ) { item = getRelevantLocatable ( ) }
21942234
2195- ItemNode debugResolvePath ( RelevantPath path ) {
2235+ ItemNode debugResolvePath ( PathExt path ) {
21962236 path = getRelevantLocatable ( ) and
21972237 result = resolvePath ( path )
21982238 }
21992239
2200- ItemNode debugResolveUseTreeListItem ( Use use , UseTree tree , RelevantPath path , SuccessorKind kind ) {
2240+ ItemNode debugResolveUseTreeListItem ( Use use , UseTree tree , PathExt path , SuccessorKind kind ) {
22012241 use = getRelevantLocatable ( ) and
22022242 result = resolveUseTreeListItem ( use , tree , path , kind )
22032243 }
0 commit comments