@@ -172,9 +172,14 @@ abstract class ItemNode extends Locatable {
172172 result = this .( TypeParamItemNode ) .resolveABound ( ) .getASuccessorRec ( name ) .( AssocItemNode )
173173 }
174174
175- /** Gets a successor named `name` of this item, if any. */
175+ /**
176+ * Gets a successor named `name` of this item, if any.
177+ *
178+ * Whenever a function exists in both source code and in library code,
179+ * both are included
180+ */
176181 cached
177- ItemNode getASuccessor ( string name ) {
182+ ItemNode getASuccessorFull ( string name ) {
178183 Stages:: PathResolutionStage:: ref ( ) and
179184 result = this .getASuccessorRec ( name )
180185 or
@@ -202,6 +207,22 @@ abstract class ItemNode extends Locatable {
202207 result .( CrateItemNode ) .isPotentialDollarCrateTarget ( )
203208 }
204209
210+ /** Gets a successor named `name` of this item, if any. */
211+ pragma [ nomagic]
212+ ItemNode getASuccessor ( string name ) {
213+ result = this .getASuccessorFull ( name ) and
214+ (
215+ // when a function exists in both source code and in library code, it is because
216+ // we also extracted the source code as library code, and hence we only want
217+ // the function from source code
218+ result .fromSource ( )
219+ or
220+ not result instanceof Function
221+ or
222+ not this .getASuccessorFull ( name ) .( Function ) .fromSource ( )
223+ )
224+ }
225+
205226 /** Gets the location of this item. */
206227 Location getLocation ( ) { result = super .getLocation ( ) }
207228}
@@ -234,7 +255,7 @@ abstract private class ModuleLikeNode extends ItemNode {
234255private class SourceFileItemNode extends ModuleLikeNode , SourceFile {
235256 pragma [ nomagic]
236257 ModuleLikeNode getSuper ( ) {
237- result = any ( ModuleItemNode mod | fileImport ( mod , this ) ) .getASuccessor ( "super" )
258+ result = any ( ModuleItemNode mod | fileImport ( mod , this ) ) .getASuccessorFull ( "super" )
238259 }
239260
240261 override string getName ( ) { result = "(source file)" }
@@ -297,7 +318,7 @@ class CrateItemNode extends ItemNode instanceof Crate {
297318 predicate isPotentialDollarCrateTarget ( ) {
298319 exists ( string name , RelevantPath p |
299320 p .isDollarCrateQualifiedPath ( name ) and
300- exists ( this .getASuccessor ( name ) )
321+ exists ( this .getASuccessorFull ( name ) )
301322 )
302323 }
303324
@@ -328,10 +349,8 @@ private class ConstItemNode extends AssocItemNode instanceof Const {
328349 or
329350 // for trait items from library code, we do not currently know if they
330351 // have default implementations or not, so we assume they do
331- exists ( TraitItemNode t |
332- this = t .getAnAssocItem ( ) and
333- not this .fromSource ( )
334- )
352+ not this .fromSource ( ) and
353+ this = any ( TraitItemNode t ) .getAnAssocItem ( )
335354 }
336355
337356 override Namespace getNamespace ( ) { result .isValue ( ) }
@@ -373,10 +392,8 @@ class FunctionItemNode extends AssocItemNode instanceof Function {
373392 or
374393 // for trait items from library code, we do not currently know if they
375394 // have default implementations or not, so we assume they do
376- exists ( TraitItemNode t |
377- this = t .getAnAssocItem ( ) and
378- not this .fromSource ( )
379- )
395+ not this .fromSource ( ) and
396+ this = any ( TraitItemNode t ) .getAnAssocItem ( )
380397 }
381398
382399 override Namespace getNamespace ( ) { result .isValue ( ) }
@@ -940,8 +957,8 @@ private predicate unqualifiedPathLookup(ItemNode encl, string name, Namespace ns
940957}
941958
942959pragma [ nomagic]
943- private ItemNode getASuccessor ( ItemNode pred , string name , Namespace ns ) {
944- result = pred .getASuccessor ( name ) and
960+ private ItemNode getASuccessorFull ( ItemNode pred , string name , Namespace ns ) {
961+ result = pred .getASuccessorFull ( name ) and
945962 ns = result .getNamespace ( )
946963}
947964
@@ -978,7 +995,7 @@ private predicate keywordLookup(ItemNode encl, string name, Namespace ns, Releva
978995
979996pragma [ nomagic]
980997private ItemNode unqualifiedPathLookup ( RelevantPath p , Namespace ns ) {
981- exists ( ItemNode encl , string name | result = getASuccessor ( encl , name , ns ) |
998+ exists ( ItemNode encl , string name | result = getASuccessorFull ( encl , name , ns ) |
982999 unqualifiedPathLookup ( encl , name , ns , p )
9831000 or
9841001 keywordLookup ( encl , name , ns , p )
@@ -1002,7 +1019,7 @@ private ItemNode resolvePath0(RelevantPath path, Namespace ns) {
10021019 or
10031020 exists ( ItemNode q , string name |
10041021 q = resolvePathQualifier ( path , name ) and
1005- result = getASuccessor ( q , name , ns )
1022+ result = getASuccessorFull ( q , name , ns )
10061023 )
10071024 or
10081025 result = resolveUseTreeListItem ( _, _, path ) and
@@ -1127,12 +1144,12 @@ private ItemNode resolveUseTreeListItem(Use use, UseTree tree, RelevantPath path
11271144 mid = resolveUseTreeListItem ( use , midTree ) and
11281145 tree = midTree .getUseTreeList ( ) .getAUseTree ( ) and
11291146 isUseTreeSubPathUnqualified ( tree , path , pragma [ only_bind_into ] ( name ) ) and
1130- result = mid .getASuccessor ( pragma [ only_bind_into ] ( name ) )
1147+ result = mid .getASuccessorFull ( pragma [ only_bind_into ] ( name ) )
11311148 )
11321149 or
11331150 exists ( ItemNode q , string name |
11341151 q = resolveUseTreeListItemQualifier ( use , tree , path , name ) and
1135- result = q .getASuccessor ( name )
1152+ result = q .getASuccessorFull ( name )
11361153 )
11371154}
11381155
@@ -1162,7 +1179,7 @@ private predicate useImportEdge(Use use, string name, ItemNode item) {
11621179 then
11631180 exists ( ItemNode encl , Namespace ns |
11641181 encl .getADescendant ( ) = use and
1165- item = getASuccessor ( used , name , ns ) and
1182+ item = getASuccessorFull ( used , name , ns ) and
11661183 // glob imports can be shadowed
11671184 not declares ( encl , ns , name ) and
11681185 not name = [ "super" , "self" , "Self" , "$crate" , "crate" ]
0 commit comments