@@ -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 ) |
@@ -1311,6 +1311,7 @@ private predicate declares(ItemNode item, Namespace ns, string name) {
13111311class RelevantPath extends Path {
13121312 RelevantPath ( ) { not this = any ( VariableAccess va ) .( PathExpr ) .getPath ( ) }
13131313
1314+ /** Holds if this is an unqualified path with the textual value `name`. */
13141315 pragma [ nomagic]
13151316 predicate isUnqualified ( string name ) {
13161317 not exists ( this .getQualifier ( ) ) and
@@ -1421,6 +1422,12 @@ private ItemNode unqualifiedPathLookup(RelevantPath p, Namespace ns, SuccessorKi
14211422pragma [ nomagic]
14221423private predicate isUnqualifiedSelfPath ( RelevantPath path ) { path .isUnqualified ( "Self" ) }
14231424
1425+ /** Holds if the trait `trait` is visible at the element `element`. */
1426+ bindingset [ element, trait]
1427+ predicate traitIsVisible ( Element element , TraitItemNode trait ) {
1428+ exists ( ItemNode encl | encl .getADescendant * ( ) = element and trait = encl .getASuccessor ( _, _) )
1429+ }
1430+
14241431pragma [ nomagic]
14251432private ItemNode resolvePathCand0 ( RelevantPath path , Namespace ns ) {
14261433 exists ( ItemNode res |
@@ -1454,6 +1461,15 @@ private ItemNode resolvePathCandQualified(
14541461 q = resolvePathCandQualifier ( qualifier , path , name ) and
14551462 result = getASuccessor ( q , name , ns , kind ) and
14561463 kind .isExternalOrBoth ( )
1464+ |
1465+ // When the result is an associated item of a trait implementation the
1466+ // implemented trait must be visible.
1467+ exists ( ImplItemNodeImpl impl |
1468+ impl .getAnAssocItem ( ) = result and
1469+ traitIsVisible ( path , impl .resolveTraitTyCand ( ) )
1470+ )
1471+ or
1472+ not exists ( ImplItemNode impl | impl .getAnAssocItem ( ) = result and impl .( Impl ) .hasTrait ( ) )
14571473 )
14581474}
14591475
@@ -1606,8 +1622,16 @@ private predicate useImportEdge(Use use, string name, ItemNode item, SuccessorKi
16061622 not tree .hasRename ( ) and
16071623 name = item .getName ( )
16081624 or
1609- name = tree .getRename ( ) .getName ( ) .getText ( ) and
1610- name != "_"
1625+ exists ( Rename rename | rename = tree .getRename ( ) |
1626+ name = rename .getName ( ) .getText ( )
1627+ or
1628+ // When the rename doesn't have a name it's an underscore import. This
1629+ // makes the imported item visible but unnameable. We represent this
1630+ // by using the name `_` which can never occur in a path. See also:
1631+ // https://doc.rust-lang.org/reference/items/use-declarations.html#r-items.use.as-underscore
1632+ not rename .hasName ( ) and
1633+ name = "_"
1634+ )
16111635 )
16121636 )
16131637 )
@@ -1693,7 +1717,7 @@ private module Debug {
16931717 useImportEdge ( use , name , item , kind )
16941718 }
16951719
1696- ItemNode debuggetASuccessor ( ItemNode i , string name , SuccessorKind kind ) {
1720+ ItemNode debugGetASuccessor ( ItemNode i , string name , SuccessorKind kind ) {
16971721 i = getRelevantLocatable ( ) and
16981722 result = i .getASuccessor ( name , kind )
16991723 }
0 commit comments