@@ -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 ) |
@@ -481,10 +481,20 @@ class ExternCrateItemNode extends ItemNode instanceof ExternCrate {
481481}
482482
483483/** An item that can occur in a trait or an `impl` block. */
484- abstract private class AssocItemNode extends ItemNode instanceof AssocItem {
484+ abstract class AssocItemNode extends ItemNode instanceof AssocItem {
485485 /** Holds if this associated item has an implementation. */
486486 abstract predicate hasImplementation ( ) ;
487487
488+ /** Holds if this item implements item `other` of `trait`. */
489+ pragma [ nomagic]
490+ predicate implements ( TraitItemNode trait , AssocItem other ) {
491+ exists ( ImplItemNode impl , string name |
492+ other = trait .getAssocItem ( pragma [ only_bind_into ] ( name ) ) and
493+ trait = impl .resolveTraitTy ( ) and
494+ this = impl .getAssocItem ( pragma [ only_bind_into ] ( name ) )
495+ )
496+ }
497+
488498 override predicate hasCanonicalPath ( Crate c ) { this .hasCanonicalPathPrefix ( c ) }
489499
490500 bindingset [ c]
@@ -1311,6 +1321,7 @@ private predicate declares(ItemNode item, Namespace ns, string name) {
13111321class RelevantPath extends Path {
13121322 RelevantPath ( ) { not this = any ( VariableAccess va ) .( PathExpr ) .getPath ( ) }
13131323
1324+ /** Holds if this is an unqualified path with the textual value `name`. */
13141325 pragma [ nomagic]
13151326 predicate isUnqualified ( string name ) {
13161327 not exists ( this .getQualifier ( ) ) and
@@ -1421,6 +1432,12 @@ private ItemNode unqualifiedPathLookup(RelevantPath p, Namespace ns, SuccessorKi
14211432pragma [ nomagic]
14221433private predicate isUnqualifiedSelfPath ( RelevantPath path ) { path .isUnqualified ( "Self" ) }
14231434
1435+ /** Holds if the trait `trait` is visible at the element `element`. */
1436+ bindingset [ element, trait]
1437+ predicate traitIsVisible ( Element element , TraitItemNode trait ) {
1438+ exists ( ItemNode encl | encl .getADescendant * ( ) = element and trait = encl .getASuccessor ( _, _) )
1439+ }
1440+
14241441pragma [ nomagic]
14251442private ItemNode resolvePathCand0 ( RelevantPath path , Namespace ns ) {
14261443 exists ( ItemNode res |
@@ -1454,6 +1471,14 @@ private ItemNode resolvePathCandQualified(
14541471 q = resolvePathCandQualifier ( qualifier , path , name ) and
14551472 result = getASuccessor ( q , name , ns , kind ) and
14561473 kind .isExternalOrBoth ( )
1474+ |
1475+ // When the result is an associated item of a trait implementation the
1476+ // implemented trait must be visible.
1477+ exists ( TraitItemNode trait |
1478+ result .( AssocItemNode ) .implements ( trait , _) and traitIsVisible ( path , trait )
1479+ )
1480+ or
1481+ not exists ( ImplItemNode impl | impl .getAnAssocItem ( ) = result and impl .( Impl ) .hasTrait ( ) )
14571482 )
14581483}
14591484
@@ -1606,8 +1631,16 @@ private predicate useImportEdge(Use use, string name, ItemNode item, SuccessorKi
16061631 not tree .hasRename ( ) and
16071632 name = item .getName ( )
16081633 or
1609- name = tree .getRename ( ) .getName ( ) .getText ( ) and
1610- name != "_"
1634+ exists ( Rename rename | rename = tree .getRename ( ) |
1635+ name = rename .getName ( ) .getText ( )
1636+ or
1637+ // When the rename doesn't have a name it's an underscore import. This
1638+ // makes the imported item visible but unnameable. We represent this
1639+ // by using the name `_` which can never occur in a path. See also:
1640+ // https://doc.rust-lang.org/reference/items/use-declarations.html#r-items.use.as-underscore
1641+ not rename .hasName ( ) and
1642+ name = "_"
1643+ )
16111644 )
16121645 )
16131646 )
@@ -1671,7 +1704,7 @@ private module Debug {
16711704 exists ( string filepath , int startline , int startcolumn , int endline , int endcolumn |
16721705 result .getLocation ( ) .hasLocationInfo ( filepath , startline , startcolumn , endline , endcolumn ) and
16731706 filepath .matches ( "%/main.rs" ) and
1674- startline = 52
1707+ startline = [ 463 .. 511 ]
16751708 )
16761709 }
16771710
@@ -1693,7 +1726,7 @@ private module Debug {
16931726 useImportEdge ( use , name , item , kind )
16941727 }
16951728
1696- ItemNode debuggetASuccessor ( ItemNode i , string name , SuccessorKind kind ) {
1729+ ItemNode debugGetASuccessor ( ItemNode i , string name , SuccessorKind kind ) {
16971730 i = getRelevantLocatable ( ) and
16981731 result = i .getASuccessor ( name , kind )
16991732 }
0 commit comments