@@ -1457,6 +1457,28 @@ private predicate crateDependencyEdge(SourceFileItemNode file, string name, Crat
14571457 not hasDeclOrDep ( file , name )
14581458}
14591459
1460+ /**
1461+ * Gets a `UseTree` that is nested under `tree`, and which needs to be resolved
1462+ * relative to the path of `tree`.
1463+ *
1464+ * `tree` is restricted to either having a path or being a direct child of some
1465+ * `use` statement.
1466+ */
1467+ private UseTree getAUseTreeUseTree ( UseTree tree ) {
1468+ result = tree .getUseTreeList ( ) .getAUseTree ( ) and
1469+ (
1470+ tree .hasPath ( )
1471+ or
1472+ tree = any ( Use u ) .getUseTree ( )
1473+ )
1474+ or
1475+ exists ( UseTree mid |
1476+ mid = getAUseTreeUseTree ( tree ) and
1477+ not mid .hasPath ( ) and
1478+ result = mid .getUseTreeList ( ) .getAUseTree ( )
1479+ )
1480+ }
1481+
14601482private predicate useTreeDeclares ( UseTree tree , string name ) {
14611483 not tree .isGlob ( ) and
14621484 not exists ( tree .getUseTreeList ( ) ) and
@@ -1470,7 +1492,7 @@ private predicate useTreeDeclares(UseTree tree, string name) {
14701492 or
14711493 exists ( UseTree mid |
14721494 useTreeDeclares ( mid , name ) and
1473- mid = tree . getUseTreeList ( ) . getAUseTree ( )
1495+ mid = getAUseTreeUseTree ( tree )
14741496 )
14751497}
14761498
@@ -1511,7 +1533,10 @@ class RelevantPath extends Path {
15111533 pragma [ nomagic]
15121534 predicate isUnqualified ( string name ) {
15131535 not exists ( this .getQualifier ( ) ) and
1514- not this = any ( UseTreeList list ) .getAUseTree ( ) .getPath ( ) .getQualifier * ( ) and
1536+ not exists ( UseTree tree |
1537+ tree .hasPath ( ) and
1538+ this = getAUseTreeUseTree ( tree ) .getPath ( ) .getQualifier * ( )
1539+ ) and
15151540 name = this .getText ( )
15161541 }
15171542
@@ -1990,7 +2015,7 @@ private ItemNode resolveUseTreeListItem(Use use, UseTree tree, RelevantPath path
19902015 exists ( UseOption useOpt | checkQualifiedVisibility ( use , result , kind , useOpt ) |
19912016 exists ( UseTree midTree , ItemNode mid , string name |
19922017 mid = resolveUseTreeListItem ( use , midTree ) and
1993- tree = midTree . getUseTreeList ( ) . getAUseTree ( ) and
2018+ tree = getAUseTreeUseTree ( midTree ) and
19942019 isUseTreeSubPathUnqualified ( tree , path , pragma [ only_bind_into ] ( name ) ) and
19952020 result = mid .getASuccessor ( pragma [ only_bind_into ] ( name ) , kind , useOpt )
19962021 )
@@ -2010,14 +2035,32 @@ private ItemNode resolveUseTreeListItemQualifier(
20102035 name = path .getText ( )
20112036}
20122037
2038+ private UseTree getAUseUseTree ( Use use ) {
2039+ result = use .getUseTree ( )
2040+ or
2041+ exists ( UseTree root |
2042+ root = use .getUseTree ( ) and
2043+ not root .hasPath ( ) and
2044+ result = getAUseTreeUseTree ( root )
2045+ )
2046+ }
2047+
20132048pragma [ nomagic]
20142049private ItemNode resolveUseTreeListItem ( Use use , UseTree tree ) {
20152050 exists ( Path path | path = tree .getPath ( ) |
2016- tree = use . getUseTree ( ) and
2051+ tree = getAUseUseTree ( use ) and
20172052 result = resolvePathCand ( path )
20182053 or
20192054 result = resolveUseTreeListItem ( use , tree , path , _)
20202055 )
2056+ or
2057+ exists ( UseTree midTree |
2058+ // `use foo::{bar, *}`; midTree = `foo` and tree = `*`
2059+ result = resolveUseTreeListItem ( use , midTree ) and
2060+ tree = getAUseTreeUseTree ( midTree ) and
2061+ tree .isGlob ( ) and
2062+ not tree .hasPath ( )
2063+ )
20212064}
20222065
20232066/** Holds if `use` imports `item` as `name`. */
@@ -2159,6 +2202,16 @@ private module Debug {
21592202 result = resolvePath ( path )
21602203 }
21612204
2205+ ItemNode debugResolveUseTreeListItem ( Use use , UseTree tree , RelevantPath path , SuccessorKind kind ) {
2206+ use = getRelevantLocatable ( ) and
2207+ result = resolveUseTreeListItem ( use , tree , path , kind )
2208+ }
2209+
2210+ ItemNode debugResolveUseTreeListItem ( Use use , UseTree tree ) {
2211+ use = getRelevantLocatable ( ) and
2212+ result = resolveUseTreeListItem ( use , tree )
2213+ }
2214+
21622215 predicate debugUseImportEdge ( Use use , string name , ItemNode item , SuccessorKind kind ) {
21632216 use = getRelevantLocatable ( ) and
21642217 useImportEdge ( use , name , item , kind )
0 commit comments