@@ -172,9 +172,14 @@ abstract class ItemNode extends Locatable {
172
172
result = this .( TypeParamItemNode ) .resolveABound ( ) .getASuccessorRec ( name ) .( AssocItemNode )
173
173
}
174
174
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
+ */
176
181
cached
177
- ItemNode getASuccessor ( string name ) {
182
+ ItemNode getASuccessorFull ( string name ) {
178
183
Stages:: PathResolutionStage:: ref ( ) and
179
184
result = this .getASuccessorRec ( name )
180
185
or
@@ -202,6 +207,22 @@ abstract class ItemNode extends Locatable {
202
207
result .( CrateItemNode ) .isPotentialDollarCrateTarget ( )
203
208
}
204
209
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
+
205
226
/** Gets the location of this item. */
206
227
Location getLocation ( ) { result = super .getLocation ( ) }
207
228
}
@@ -234,7 +255,7 @@ abstract private class ModuleLikeNode extends ItemNode {
234
255
private class SourceFileItemNode extends ModuleLikeNode , SourceFile {
235
256
pragma [ nomagic]
236
257
ModuleLikeNode getSuper ( ) {
237
- result = any ( ModuleItemNode mod | fileImport ( mod , this ) ) .getASuccessor ( "super" )
258
+ result = any ( ModuleItemNode mod | fileImport ( mod , this ) ) .getASuccessorFull ( "super" )
238
259
}
239
260
240
261
override string getName ( ) { result = "(source file)" }
@@ -297,7 +318,7 @@ class CrateItemNode extends ItemNode instanceof Crate {
297
318
predicate isPotentialDollarCrateTarget ( ) {
298
319
exists ( string name , RelevantPath p |
299
320
p .isDollarCrateQualifiedPath ( name ) and
300
- exists ( this .getASuccessor ( name ) )
321
+ exists ( this .getASuccessorFull ( name ) )
301
322
)
302
323
}
303
324
@@ -323,7 +344,14 @@ abstract private class AssocItemNode extends ItemNode, AssocItem {
323
344
private class ConstItemNode extends AssocItemNode instanceof Const {
324
345
override string getName ( ) { result = Const .super .getName ( ) .getText ( ) }
325
346
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
+ }
327
355
328
356
override Namespace getNamespace ( ) { result .isValue ( ) }
329
357
@@ -359,7 +387,14 @@ private class VariantItemNode extends ItemNode instanceof Variant {
359
387
class FunctionItemNode extends AssocItemNode instanceof Function {
360
388
override string getName ( ) { result = Function .super .getName ( ) .getText ( ) }
361
389
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
+ }
363
398
364
399
override Namespace getNamespace ( ) { result .isValue ( ) }
365
400
@@ -862,6 +897,12 @@ class RelevantPath extends Path {
862
897
this .getQualifier ( ) .( RelevantPath ) .isCratePath ( "$crate" , _) and
863
898
this .getText ( ) = name
864
899
}
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
+ }
865
906
}
866
907
867
908
private predicate isModule ( ItemNode m ) { m instanceof Module }
@@ -916,8 +957,8 @@ private predicate unqualifiedPathLookup(ItemNode encl, string name, Namespace ns
916
957
}
917
958
918
959
pragma [ 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
921
962
ns = result .getNamespace ( )
922
963
}
923
964
@@ -954,7 +995,7 @@ private predicate keywordLookup(ItemNode encl, string name, Namespace ns, Releva
954
995
955
996
pragma [ nomagic]
956
997
private 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 ) |
958
999
unqualifiedPathLookup ( encl , name , ns , p )
959
1000
or
960
1001
keywordLookup ( encl , name , ns , p )
@@ -978,7 +1019,7 @@ private ItemNode resolvePath0(RelevantPath path, Namespace ns) {
978
1019
or
979
1020
exists ( ItemNode q , string name |
980
1021
q = resolvePathQualifier ( path , name ) and
981
- result = getASuccessor ( q , name , ns )
1022
+ result = getASuccessorFull ( q , name , ns )
982
1023
)
983
1024
or
984
1025
result = resolveUseTreeListItem ( _, _, path ) and
@@ -1029,6 +1070,7 @@ pragma[nomagic]
1029
1070
private ItemNode resolvePathPrivate (
1030
1071
RelevantPath path , ModuleLikeNode itemParent , ModuleLikeNode pathParent
1031
1072
) {
1073
+ not path .requiresExtractorWorkaround ( ) and
1032
1074
result = resolvePath1 ( path ) and
1033
1075
itemParent = result .getImmediateParentModule ( ) and
1034
1076
not result .isPublic ( ) and
@@ -1062,7 +1104,11 @@ private ModuleLikeNode getAPrivateVisibleModule(ModuleLikeNode itemParent) {
1062
1104
cached
1063
1105
ItemNode resolvePath ( RelevantPath path ) {
1064
1106
result = resolvePath1 ( path ) and
1065
- result .isPublic ( )
1107
+ (
1108
+ result .isPublic ( )
1109
+ or
1110
+ path .requiresExtractorWorkaround ( )
1111
+ )
1066
1112
or
1067
1113
exists ( ModuleLikeNode itemParent , ModuleLikeNode pathParent |
1068
1114
result = resolvePathPrivate ( path , itemParent , pathParent ) and
@@ -1098,12 +1144,12 @@ private ItemNode resolveUseTreeListItem(Use use, UseTree tree, RelevantPath path
1098
1144
mid = resolveUseTreeListItem ( use , midTree ) and
1099
1145
tree = midTree .getUseTreeList ( ) .getAUseTree ( ) and
1100
1146
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 ) )
1102
1148
)
1103
1149
or
1104
1150
exists ( ItemNode q , string name |
1105
1151
q = resolveUseTreeListItemQualifier ( use , tree , path , name ) and
1106
- result = q .getASuccessor ( name )
1152
+ result = q .getASuccessorFull ( name )
1107
1153
)
1108
1154
}
1109
1155
@@ -1133,7 +1179,7 @@ private predicate useImportEdge(Use use, string name, ItemNode item) {
1133
1179
then
1134
1180
exists ( ItemNode encl , Namespace ns |
1135
1181
encl .getADescendant ( ) = use and
1136
- item = getASuccessor ( used , name , ns ) and
1182
+ item = getASuccessorFull ( used , name , ns ) and
1137
1183
// glob imports can be shadowed
1138
1184
not declares ( encl , ns , name ) and
1139
1185
not name = [ "super" , "self" , "Self" , "$crate" , "crate" ]
0 commit comments