@@ -1436,6 +1436,24 @@ private predicate crateDependencyEdge(SourceFileItemNode file, string name, Crat
14361436 not hasDeclOrDep ( file , name )
14371437}
14381438
1439+ /**
1440+ * Gets a `UseTree` that is nested under `tree`, and which needs to be resolved
1441+ * relative to the path of `tree`.
1442+ *
1443+ * `tree` is restricted to either having a path or being a direct child of some
1444+ * `use` statement without a path.
1445+ */
1446+ private UseTree getAUseTreeUseTree ( UseTree tree ) {
1447+ result = tree .getUseTreeList ( ) .getAUseTree ( ) and
1448+ ( if tree .hasPath ( ) then any ( ) else tree = any ( Use u ) .getUseTree ( ) )
1449+ or
1450+ exists ( UseTree mid |
1451+ mid = getAUseTreeUseTree ( tree ) and
1452+ not mid .hasPath ( ) and
1453+ result = mid .getUseTreeList ( ) .getAUseTree ( )
1454+ )
1455+ }
1456+
14391457private predicate useTreeDeclares ( UseTree tree , string name ) {
14401458 not tree .isGlob ( ) and
14411459 not exists ( tree .getUseTreeList ( ) ) and
@@ -1449,7 +1467,7 @@ private predicate useTreeDeclares(UseTree tree, string name) {
14491467 or
14501468 exists ( UseTree mid |
14511469 useTreeDeclares ( mid , name ) and
1452- mid = tree . getUseTreeList ( ) . getAUseTree ( )
1470+ mid = getAUseTreeUseTree ( tree )
14531471 )
14541472}
14551473
@@ -1490,7 +1508,10 @@ class RelevantPath extends Path {
14901508 pragma [ nomagic]
14911509 predicate isUnqualified ( string name ) {
14921510 not exists ( this .getQualifier ( ) ) and
1493- not this = any ( UseTreeList list ) .getAUseTree ( ) .getPath ( ) .getQualifier * ( ) and
1511+ not exists ( UseTree tree |
1512+ tree .hasPath ( ) and
1513+ this = getAUseTreeUseTree ( tree ) .getPath ( ) .getQualifier * ( )
1514+ ) and
14941515 name = this .getText ( )
14951516 }
14961517
@@ -1969,7 +1990,7 @@ private ItemNode resolveUseTreeListItem(Use use, UseTree tree, RelevantPath path
19691990 exists ( UseOption useOpt | checkQualifiedVisibility ( use , result , kind , useOpt ) |
19701991 exists ( UseTree midTree , ItemNode mid , string name |
19711992 mid = resolveUseTreeListItem ( use , midTree ) and
1972- tree = midTree . getUseTreeList ( ) . getAUseTree ( ) and
1993+ tree = getAUseTreeUseTree ( midTree ) and
19731994 isUseTreeSubPathUnqualified ( tree , path , pragma [ only_bind_into ] ( name ) ) and
19741995 result = mid .getASuccessor ( pragma [ only_bind_into ] ( name ) , kind , useOpt )
19751996 )
@@ -1989,14 +2010,31 @@ private ItemNode resolveUseTreeListItemQualifier(
19892010 name = path .getText ( )
19902011}
19912012
2013+ private UseTree getAUseUseTree ( Use use ) {
2014+ exists ( UseTree root | root = use .getUseTree ( ) |
2015+ result = root
2016+ or
2017+ not root .hasPath ( ) and
2018+ result = getAUseTreeUseTree ( root )
2019+ )
2020+ }
2021+
19922022pragma [ nomagic]
19932023private ItemNode resolveUseTreeListItem ( Use use , UseTree tree ) {
19942024 exists ( Path path | path = tree .getPath ( ) |
1995- tree = use . getUseTree ( ) and
2025+ tree = getAUseUseTree ( use ) and
19962026 result = resolvePathCand ( path )
19972027 or
19982028 result = resolveUseTreeListItem ( use , tree , path , _)
19992029 )
2030+ or
2031+ exists ( UseTree midTree |
2032+ // `use foo::{bar, *}`; midTree = `foo` and tree = `*`
2033+ result = resolveUseTreeListItem ( use , midTree ) and
2034+ tree = getAUseTreeUseTree ( midTree ) and
2035+ tree .isGlob ( ) and
2036+ not tree .hasPath ( )
2037+ )
20002038}
20012039
20022040/** Holds if `use` imports `item` as `name`. */
@@ -2138,6 +2176,16 @@ private module Debug {
21382176 result = resolvePath ( path )
21392177 }
21402178
2179+ ItemNode debugResolveUseTreeListItem ( Use use , UseTree tree , RelevantPath path , SuccessorKind kind ) {
2180+ use = getRelevantLocatable ( ) and
2181+ result = resolveUseTreeListItem ( use , tree , path , kind )
2182+ }
2183+
2184+ ItemNode debugResolveUseTreeListItem ( Use use , UseTree tree ) {
2185+ use = getRelevantLocatable ( ) and
2186+ result = resolveUseTreeListItem ( use , tree )
2187+ }
2188+
21412189 predicate debugUseImportEdge ( Use use , string name , ItemNode item , SuccessorKind kind ) {
21422190 use = getRelevantLocatable ( ) and
21432191 useImportEdge ( use , name , item , kind )
0 commit comments