@@ -1457,6 +1457,24 @@ 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 without a path.
1466+ */
1467+ private UseTree getAUseTreeUseTree ( UseTree tree ) {
1468+ result = tree .getUseTreeList ( ) .getAUseTree ( ) and
1469+ ( if tree .hasPath ( ) then any ( ) else tree = any ( Use u ) .getUseTree ( ) )
1470+ or
1471+ exists ( UseTree mid |
1472+ mid = getAUseTreeUseTree ( tree ) and
1473+ not mid .hasPath ( ) and
1474+ result = mid .getUseTreeList ( ) .getAUseTree ( )
1475+ )
1476+ }
1477+
14601478private predicate useTreeDeclares ( UseTree tree , string name ) {
14611479 not tree .isGlob ( ) and
14621480 not exists ( tree .getUseTreeList ( ) ) and
@@ -1470,7 +1488,7 @@ private predicate useTreeDeclares(UseTree tree, string name) {
14701488 or
14711489 exists ( UseTree mid |
14721490 useTreeDeclares ( mid , name ) and
1473- mid = tree . getUseTreeList ( ) . getAUseTree ( )
1491+ mid = getAUseTreeUseTree ( tree )
14741492 )
14751493}
14761494
@@ -1511,7 +1529,10 @@ class RelevantPath extends Path {
15111529 pragma [ nomagic]
15121530 predicate isUnqualified ( string name ) {
15131531 not exists ( this .getQualifier ( ) ) and
1514- not this = any ( UseTreeList list ) .getAUseTree ( ) .getPath ( ) .getQualifier * ( ) and
1532+ not exists ( UseTree tree |
1533+ tree .hasPath ( ) and
1534+ this = getAUseTreeUseTree ( tree ) .getPath ( ) .getQualifier * ( )
1535+ ) and
15151536 name = this .getText ( )
15161537 }
15171538
@@ -1990,7 +2011,7 @@ private ItemNode resolveUseTreeListItem(Use use, UseTree tree, RelevantPath path
19902011 exists ( UseOption useOpt | checkQualifiedVisibility ( use , result , kind , useOpt ) |
19912012 exists ( UseTree midTree , ItemNode mid , string name |
19922013 mid = resolveUseTreeListItem ( use , midTree ) and
1993- tree = midTree . getUseTreeList ( ) . getAUseTree ( ) and
2014+ tree = getAUseTreeUseTree ( midTree ) and
19942015 isUseTreeSubPathUnqualified ( tree , path , pragma [ only_bind_into ] ( name ) ) and
19952016 result = mid .getASuccessor ( pragma [ only_bind_into ] ( name ) , kind , useOpt )
19962017 )
@@ -2010,14 +2031,31 @@ private ItemNode resolveUseTreeListItemQualifier(
20102031 name = path .getText ( )
20112032}
20122033
2034+ private UseTree getAUseUseTree ( Use use ) {
2035+ exists ( UseTree root | root = use .getUseTree ( ) |
2036+ result = root
2037+ or
2038+ not root .hasPath ( ) and
2039+ result = getAUseTreeUseTree ( root )
2040+ )
2041+ }
2042+
20132043pragma [ nomagic]
20142044private ItemNode resolveUseTreeListItem ( Use use , UseTree tree ) {
20152045 exists ( Path path | path = tree .getPath ( ) |
2016- tree = use . getUseTree ( ) and
2046+ tree = getAUseUseTree ( use ) and
20172047 result = resolvePathCand ( path )
20182048 or
20192049 result = resolveUseTreeListItem ( use , tree , path , _)
20202050 )
2051+ or
2052+ exists ( UseTree midTree |
2053+ // `use foo::{bar, *}`; midTree = `foo` and tree = `*`
2054+ result = resolveUseTreeListItem ( use , midTree ) and
2055+ tree = getAUseTreeUseTree ( midTree ) and
2056+ tree .isGlob ( ) and
2057+ not tree .hasPath ( )
2058+ )
20212059}
20222060
20232061/** Holds if `use` imports `item` as `name`. */
@@ -2159,6 +2197,16 @@ private module Debug {
21592197 result = resolvePath ( path )
21602198 }
21612199
2200+ ItemNode debugResolveUseTreeListItem ( Use use , UseTree tree , RelevantPath path , SuccessorKind kind ) {
2201+ use = getRelevantLocatable ( ) and
2202+ result = resolveUseTreeListItem ( use , tree , path , kind )
2203+ }
2204+
2205+ ItemNode debugResolveUseTreeListItem ( Use use , UseTree tree ) {
2206+ use = getRelevantLocatable ( ) and
2207+ result = resolveUseTreeListItem ( use , tree )
2208+ }
2209+
21622210 predicate debugUseImportEdge ( Use use , string name , ItemNode item , SuccessorKind kind ) {
21632211 use = getRelevantLocatable ( ) and
21642212 useImportEdge ( use , name , item , kind )
0 commit comments