@@ -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 |
@@ -1446,6 +1453,18 @@ private ItemNode resolvePathCandQualifier(RelevantPath qualifier, RelevantPath p
14461453 name = path .getText ( )
14471454}
14481455
1456+ pragma [ nomagic]
1457+ private TraitItemNode assocItemImplementsTrait ( AssocItemNode assoc ) {
1458+ exists ( ImplItemNodeImpl impl |
1459+ impl .getAnAssocItem ( ) = assoc and
1460+ result = impl .resolveTraitTyCand ( )
1461+ )
1462+ }
1463+
1464+ /**
1465+ * Gets the item that `path` resolves to in `ns` when `qualifier` is the
1466+ * qualifier of `path` and `qualifier` resolves to `q`, if any.
1467+ */
14491468pragma [ nomagic]
14501469private ItemNode resolvePathCandQualified (
14511470 RelevantPath qualifier , ItemNode q , RelevantPath path , Namespace ns
@@ -1524,7 +1543,14 @@ private ItemNode resolvePathCand(RelevantPath path) {
15241543cached
15251544ItemNode resolvePath ( RelevantPath path ) {
15261545 result = resolvePathCand ( path ) and
1527- not path = any ( Path parent | exists ( resolvePathCand ( parent ) ) ) .getQualifier ( )
1546+ not path = any ( Path parent | exists ( resolvePathCand ( parent ) ) ) .getQualifier ( ) and
1547+ (
1548+ // When the result is an associated item of a trait implementation the
1549+ // implemented trait must be visible.
1550+ traitIsVisible ( path , assocItemImplementsTrait ( pragma [ only_bind_out ] ( result ) ) )
1551+ or
1552+ not exists ( ImplItemNode impl | impl .getAnAssocItem ( ) = result and impl .( Impl ) .hasTrait ( ) )
1553+ )
15281554 or
15291555 // if `path` is the qualifier of a resolvable `parent`, then we should
15301556 // resolve `path` to something consistent with what `parent` resolves to
@@ -1606,8 +1632,16 @@ private predicate useImportEdge(Use use, string name, ItemNode item, SuccessorKi
16061632 not tree .hasRename ( ) and
16071633 name = item .getName ( )
16081634 or
1609- name = tree .getRename ( ) .getName ( ) .getText ( ) and
1610- name != "_"
1635+ exists ( Rename rename | rename = tree .getRename ( ) |
1636+ name = rename .getName ( ) .getText ( )
1637+ or
1638+ // When the rename doesn't have a name it's an underscore import. This
1639+ // makes the imported item visible but unnameable. We represent this
1640+ // by using the name `_` which can never occur in a path. See also:
1641+ // https://doc.rust-lang.org/reference/items/use-declarations.html#r-items.use.as-underscore
1642+ not rename .hasName ( ) and
1643+ name = "_"
1644+ )
16111645 )
16121646 )
16131647 )
@@ -1693,7 +1727,7 @@ private module Debug {
16931727 useImportEdge ( use , name , item , kind )
16941728 }
16951729
1696- ItemNode debuggetASuccessor ( ItemNode i , string name , SuccessorKind kind ) {
1730+ ItemNode debugGetASuccessor ( ItemNode i , string name , SuccessorKind kind ) {
16971731 i = getRelevantLocatable ( ) and
16981732 result = i .getASuccessor ( name , kind )
16991733 }
0 commit comments