@@ -216,7 +216,7 @@ abstract class ItemNode extends Locatable {
216216 // items made available through `use` are available to nodes that contain the `use`
217217 exists ( UseItemNode use |
218218 use = this .getASuccessor ( _, _) and
219- result = use .( ItemNode ) . getASuccessor ( name , kind )
219+ result = use .getASuccessor ( name , kind )
220220 )
221221 or
222222 exists ( ExternCrateItemNode ec | result = ec .( ItemNode ) .getASuccessor ( name , kind ) |
@@ -476,10 +476,20 @@ class ExternCrateItemNode extends ItemNode instanceof ExternCrate {
476476}
477477
478478/** An item that can occur in a trait or an `impl` block. */
479- abstract private class AssocItemNode extends ItemNode instanceof AssocItem {
479+ abstract class AssocItemNode extends ItemNode instanceof AssocItem {
480480 /** Holds if this associated item has an implementation. */
481481 abstract predicate hasImplementation ( ) ;
482482
483+ /** Holds if this item implements item `other` of `trait`. */
484+ pragma [ nomagic]
485+ predicate implements ( TraitItemNode trait , AssocItem other ) {
486+ exists ( ImplItemNode impl , string name |
487+ other = trait .getAssocItem ( pragma [ only_bind_into ] ( name ) ) and
488+ trait = impl .resolveTraitTy ( ) and
489+ this = impl .getAssocItem ( pragma [ only_bind_into ] ( name ) )
490+ )
491+ }
492+
483493 override predicate hasCanonicalPath ( Crate c ) { this .hasCanonicalPathPrefix ( c ) }
484494
485495 bindingset [ c]
@@ -1215,6 +1225,7 @@ private predicate declares(ItemNode item, Namespace ns, string name) {
12151225class RelevantPath extends Path {
12161226 RelevantPath ( ) { not this = any ( VariableAccess va ) .( PathExpr ) .getPath ( ) }
12171227
1228+ /** Holds if this is an unqualified path with the textual value `name`. */
12181229 pragma [ nomagic]
12191230 predicate isUnqualified ( string name ) {
12201231 not exists ( this .getQualifier ( ) ) and
@@ -1325,6 +1336,12 @@ private ItemNode unqualifiedPathLookup(RelevantPath p, Namespace ns, SuccessorKi
13251336pragma [ nomagic]
13261337private predicate isUnqualifiedSelfPath ( RelevantPath path ) { path .isUnqualified ( "Self" ) }
13271338
1339+ /** Holds if the trait `trait` is visible at the element `element`. */
1340+ bindingset [ element, trait]
1341+ predicate traitIsVisible ( Element element , TraitItemNode trait ) {
1342+ exists ( ItemNode encl | encl .getADescendant * ( ) = element and trait = encl .getASuccessor ( _, _) )
1343+ }
1344+
13281345pragma [ nomagic]
13291346private ItemNode resolvePath0 ( RelevantPath path , Namespace ns , SuccessorKind kind ) {
13301347 exists ( ItemNode res |
@@ -1341,6 +1358,14 @@ private ItemNode resolvePath0(RelevantPath path, Namespace ns, SuccessorKind kin
13411358 q = resolvePathQualifier ( path , name ) and
13421359 result = getASuccessor ( q , name , ns , kind ) and
13431360 kind .isExternalOrBoth ( )
1361+ |
1362+ // When the result is an associated item of a trait implementation the
1363+ // implemented trait must be visible.
1364+ exists ( TraitItemNode trait |
1365+ result .( AssocItemNode ) .implements ( trait , _) and traitIsVisible ( path , trait )
1366+ )
1367+ or
1368+ not exists ( ImplItemNode impl | impl .getAnAssocItem ( ) = result and impl .( Impl ) .hasTrait ( ) )
13441369 )
13451370 or
13461371 result = resolveUseTreeListItem ( _, _, path , kind ) and
@@ -1477,8 +1502,16 @@ private predicate useImportEdge(Use use, string name, ItemNode item, SuccessorKi
14771502 not tree .hasRename ( ) and
14781503 name = item .getName ( )
14791504 or
1480- name = tree .getRename ( ) .getName ( ) .getText ( ) and
1481- name != "_"
1505+ exists ( Rename rename | rename = tree .getRename ( ) |
1506+ name = rename .getName ( ) .getText ( )
1507+ or
1508+ // When the rename doesn't have a name it's an underscore import. This
1509+ // makes the imported item visible but unnameable. We represent this
1510+ // by using the name `_` which can never occur in a path. See also:
1511+ // https://doc.rust-lang.org/reference/items/use-declarations.html#r-items.use.as-underscore
1512+ not rename .hasName ( ) and
1513+ name = "_"
1514+ )
14821515 )
14831516 )
14841517 )
@@ -1550,7 +1583,7 @@ private module Debug {
15501583 exists ( string filepath , int startline , int startcolumn , int endline , int endcolumn |
15511584 result .getLocation ( ) .hasLocationInfo ( filepath , startline , startcolumn , endline , endcolumn ) and
15521585 filepath .matches ( "%/main.rs" ) and
1553- startline = 52
1586+ startline = [ 463 .. 511 ]
15541587 )
15551588 }
15561589
@@ -1572,7 +1605,7 @@ private module Debug {
15721605 useImportEdge ( use , name , item , kind )
15731606 }
15741607
1575- ItemNode debuggetASuccessor ( ItemNode i , string name , SuccessorKind kind ) {
1608+ ItemNode debugGetASuccessor ( ItemNode i , string name , SuccessorKind kind ) {
15761609 i = getRelevantLocatable ( ) and
15771610 result = i .getASuccessor ( name , kind )
15781611 }
0 commit comments