@@ -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
@@ -323,7 +344,14 @@ abstract private class AssocItemNode extends ItemNode, AssocItem {
323344private class ConstItemNode extends AssocItemNode instanceof Const {
324345 override string getName ( ) { result = Const .super .getName ( ) .getText ( ) }
325346
326- override predicate hasImplementation ( ) { super .hasBody ( ) }
347+ override predicate hasImplementation ( ) {
348+ super .hasBody ( )
349+ or
350+ // for trait items from library code, we do not currently know if they
351+ // have default implementations or not, so we assume they do
352+ not this .fromSource ( ) and
353+ this = any ( TraitItemNode t ) .getAnAssocItem ( )
354+ }
327355
328356 override Namespace getNamespace ( ) { result .isValue ( ) }
329357
@@ -359,7 +387,14 @@ private class VariantItemNode extends ItemNode instanceof Variant {
359387class FunctionItemNode extends AssocItemNode instanceof Function {
360388 override string getName ( ) { result = Function .super .getName ( ) .getText ( ) }
361389
362- override predicate hasImplementation ( ) { super .hasBody ( ) }
390+ override predicate hasImplementation ( ) {
391+ super .hasBody ( )
392+ or
393+ // for trait items from library code, we do not currently know if they
394+ // have default implementations or not, so we assume they do
395+ not this .fromSource ( ) and
396+ this = any ( TraitItemNode t ) .getAnAssocItem ( )
397+ }
363398
364399 override Namespace getNamespace ( ) { result .isValue ( ) }
365400
@@ -862,6 +897,12 @@ class RelevantPath extends Path {
862897 this .getQualifier ( ) .( RelevantPath ) .isCratePath ( "$crate" , _) and
863898 this .getText ( ) = name
864899 }
900+
901+ // TODO: Remove once the crate graph extractor generates publicly visible paths
902+ predicate requiresExtractorWorkaround ( ) {
903+ not this .fromSource ( ) and
904+ this = any ( RelevantPath p ) .getQualifier ( )
905+ }
865906}
866907
867908private predicate isModule ( ItemNode m ) { m instanceof Module }
@@ -916,8 +957,8 @@ private predicate unqualifiedPathLookup(ItemNode encl, string name, Namespace ns
916957}
917958
918959pragma [ nomagic]
919- private ItemNode getASuccessor ( ItemNode pred , string name , Namespace ns ) {
920- result = pred .getASuccessor ( name ) and
960+ private ItemNode getASuccessorFull ( ItemNode pred , string name , Namespace ns ) {
961+ result = pred .getASuccessorFull ( name ) and
921962 ns = result .getNamespace ( )
922963}
923964
@@ -954,7 +995,7 @@ private predicate keywordLookup(ItemNode encl, string name, Namespace ns, Releva
954995
955996pragma [ nomagic]
956997private ItemNode unqualifiedPathLookup ( RelevantPath p , Namespace ns ) {
957- exists ( ItemNode encl , string name | result = getASuccessor ( encl , name , ns ) |
998+ exists ( ItemNode encl , string name | result = getASuccessorFull ( encl , name , ns ) |
958999 unqualifiedPathLookup ( encl , name , ns , p )
9591000 or
9601001 keywordLookup ( encl , name , ns , p )
@@ -978,7 +1019,7 @@ private ItemNode resolvePath0(RelevantPath path, Namespace ns) {
9781019 or
9791020 exists ( ItemNode q , string name |
9801021 q = resolvePathQualifier ( path , name ) and
981- result = getASuccessor ( q , name , ns )
1022+ result = getASuccessorFull ( q , name , ns )
9821023 )
9831024 or
9841025 result = resolveUseTreeListItem ( _, _, path ) and
@@ -1029,6 +1070,7 @@ pragma[nomagic]
10291070private ItemNode resolvePathPrivate (
10301071 RelevantPath path , ModuleLikeNode itemParent , ModuleLikeNode pathParent
10311072) {
1073+ not path .requiresExtractorWorkaround ( ) and
10321074 result = resolvePath1 ( path ) and
10331075 itemParent = result .getImmediateParentModule ( ) and
10341076 not result .isPublic ( ) and
@@ -1062,7 +1104,11 @@ private ModuleLikeNode getAPrivateVisibleModule(ModuleLikeNode itemParent) {
10621104cached
10631105ItemNode resolvePath ( RelevantPath path ) {
10641106 result = resolvePath1 ( path ) and
1065- result .isPublic ( )
1107+ (
1108+ result .isPublic ( )
1109+ or
1110+ path .requiresExtractorWorkaround ( )
1111+ )
10661112 or
10671113 exists ( ModuleLikeNode itemParent , ModuleLikeNode pathParent |
10681114 result = resolvePathPrivate ( path , itemParent , pathParent ) and
@@ -1098,12 +1144,12 @@ private ItemNode resolveUseTreeListItem(Use use, UseTree tree, RelevantPath path
10981144 mid = resolveUseTreeListItem ( use , midTree ) and
10991145 tree = midTree .getUseTreeList ( ) .getAUseTree ( ) and
11001146 isUseTreeSubPathUnqualified ( tree , path , pragma [ only_bind_into ] ( name ) ) and
1101- result = mid .getASuccessor ( pragma [ only_bind_into ] ( name ) )
1147+ result = mid .getASuccessorFull ( pragma [ only_bind_into ] ( name ) )
11021148 )
11031149 or
11041150 exists ( ItemNode q , string name |
11051151 q = resolveUseTreeListItemQualifier ( use , tree , path , name ) and
1106- result = q .getASuccessor ( name )
1152+ result = q .getASuccessorFull ( name )
11071153 )
11081154}
11091155
@@ -1133,7 +1179,7 @@ private predicate useImportEdge(Use use, string name, ItemNode item) {
11331179 then
11341180 exists ( ItemNode encl , Namespace ns |
11351181 encl .getADescendant ( ) = use and
1136- item = getASuccessor ( used , name , ns ) and
1182+ item = getASuccessorFull ( used , name , ns ) and
11371183 // glob imports can be shadowed
11381184 not declares ( encl , ns , name ) and
11391185 not name = [ "super" , "self" , "Self" , "$crate" , "crate" ]
0 commit comments