@@ -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 |
@@ -1447,7 +1454,15 @@ private ItemNode resolvePathCandQualifier(RelevantPath qualifier, RelevantPath p
14471454}
14481455
14491456pragma [ nomagic]
1450- private ItemNode resolvePathCandQualified (
1457+ private TraitItemNode assocItemImplementsTrait ( AssocItemNode assoc ) {
1458+ exists ( ImplItemNodeImpl impl |
1459+ impl .getAnAssocItem ( ) = assoc and
1460+ result = impl .resolveTraitTyCand ( )
1461+ )
1462+ }
1463+
1464+ pragma [ nomagic]
1465+ private ItemNode resolvePathCandQualified0 (
14511466 RelevantPath qualifier , ItemNode q , RelevantPath path , Namespace ns
14521467) {
14531468 exists ( string name , SuccessorKind kind |
@@ -1457,6 +1472,20 @@ private ItemNode resolvePathCandQualified(
14571472 )
14581473}
14591474
1475+ pragma [ nomagic]
1476+ private ItemNode resolvePathCandQualified (
1477+ RelevantPath qualifier , ItemNode q , RelevantPath path , Namespace ns
1478+ ) {
1479+ result = resolvePathCandQualified0 ( qualifier , q , path , ns ) and
1480+ (
1481+ // When the result is an associated item of a trait implementation the
1482+ // implemented trait must be visible.
1483+ traitIsVisible ( path , assocItemImplementsTrait ( pragma [ only_bind_out ] ( result ) ) )
1484+ or
1485+ not exists ( ImplItemNode impl | impl .getAnAssocItem ( ) = result and impl .( Impl ) .hasTrait ( ) )
1486+ )
1487+ }
1488+
14601489/** Holds if path `p` must be looked up in namespace `n`. */
14611490private predicate pathUsesNamespace ( Path p , Namespace n ) {
14621491 n .isValue ( ) and
@@ -1606,8 +1635,16 @@ private predicate useImportEdge(Use use, string name, ItemNode item, SuccessorKi
16061635 not tree .hasRename ( ) and
16071636 name = item .getName ( )
16081637 or
1609- name = tree .getRename ( ) .getName ( ) .getText ( ) and
1610- name != "_"
1638+ exists ( Rename rename | rename = tree .getRename ( ) |
1639+ name = rename .getName ( ) .getText ( )
1640+ or
1641+ // When the rename doesn't have a name it's an underscore import. This
1642+ // makes the imported item visible but unnameable. We represent this
1643+ // by using the name `_` which can never occur in a path. See also:
1644+ // https://doc.rust-lang.org/reference/items/use-declarations.html#r-items.use.as-underscore
1645+ not rename .hasName ( ) and
1646+ name = "_"
1647+ )
16111648 )
16121649 )
16131650 )
@@ -1693,7 +1730,7 @@ private module Debug {
16931730 useImportEdge ( use , name , item , kind )
16941731 }
16951732
1696- ItemNode debuggetASuccessor ( ItemNode i , string name , SuccessorKind kind ) {
1733+ ItemNode debugGetASuccessor ( ItemNode i , string name , SuccessorKind kind ) {
16971734 i = getRelevantLocatable ( ) and
16981735 result = i .getASuccessor ( name , kind )
16991736 }
0 commit comments