@@ -2154,12 +2154,13 @@ private predicate methodCallHasImplCandidate(MethodCall mc, Impl impl) {
2154
2154
2155
2155
private module BlanketImplementation {
2156
2156
/**
2157
- * Holds if `impl` is a blanket implementation, that is, an implementation of a
2158
- * trait for a type parameter .
2157
+ * Gets the type parameter for which `impl` is a blanket implementation, if
2158
+ * any .
2159
2159
*/
2160
2160
private TypeParamItemNode getBlanketImplementationTypeParam ( Impl impl ) {
2161
2161
result = impl .( ImplItemNode ) .resolveSelfTy ( ) and
2162
2162
result = impl .getGenericParamList ( ) .getAGenericParam ( ) and
2163
+ // This impl block is not superseded by the expansion of an attribute macro.
2163
2164
not exists ( impl .getAttributeMacroExpansion ( ) )
2164
2165
}
2165
2166
@@ -2173,8 +2174,17 @@ private module BlanketImplementation {
2173
2174
}
2174
2175
2175
2176
/**
2176
- * Holds if `impl1` and `impl2` are duplicates and `impl2` is more "canonical"
2177
- * than `impl1`.
2177
+ * Holds if `impl1` and `impl2` are duplicates and `impl2` is strictly more
2178
+ * "canonical" than `impl1`.
2179
+ *
2180
+ * Libraries can often occur several times in the database for different
2181
+ * library versions. This causes the same blanket implementations to exist
2182
+ * multiple times, and these add no useful information.
2183
+ *
2184
+ * We detect these duplicates based on some simple heuristics (same trait
2185
+ * name, file name, etc.). For these duplicates we select the one with the
2186
+ * greatest file name (which usually is also the one with the greatest library
2187
+ * version in the path)
2178
2188
*/
2179
2189
predicate duplicatedImpl ( Impl impl1 , Impl impl2 ) {
2180
2190
exists ( string fileName , string traitName , int arity , string tpName |
@@ -2185,23 +2195,10 @@ private module BlanketImplementation {
2185
2195
)
2186
2196
}
2187
2197
2188
- predicate hasNoDuplicates ( Impl impl ) {
2198
+ predicate isCanonicalImpl ( Impl impl ) {
2189
2199
not duplicatedImpl ( impl , _) and isBlanketImplementation ( impl )
2190
2200
}
2191
2201
2192
- /**
2193
- * We currently consider blanket implementations to be in scope "globally",
2194
- * even though they actually need to be imported to be used. One downside of
2195
- * this is that the libraries included in the database can often occur several
2196
- * times for different library versions. This causes the same blanket
2197
- * implementations to exist multiple times, and these add no useful
2198
- * information.
2199
- *
2200
- * We detect these duplicates based on some files heuristic (same trait name,
2201
- * file name, etc.). For these duplicates we select the one with the greatest
2202
- * file name (which usually is also the one with the greatest library version
2203
- * in the path)
2204
- */
2205
2202
Impl getCanonicalImpl ( Impl impl ) {
2206
2203
result =
2207
2204
max ( Impl impl0 , Location l |
@@ -2210,7 +2207,7 @@ private module BlanketImplementation {
2210
2207
impl0 order by l .getFile ( ) .getAbsolutePath ( ) , l .getStartLine ( )
2211
2208
)
2212
2209
or
2213
- hasNoDuplicates ( impl ) and result = impl
2210
+ isCanonicalImpl ( impl ) and result = impl
2214
2211
}
2215
2212
2216
2213
predicate isCanonicalBlanketImplementation ( Impl impl ) { impl = getCanonicalImpl ( impl ) }
@@ -2223,11 +2220,10 @@ private module BlanketImplementation {
2223
2220
t =
2224
2221
min ( Trait trait , int i |
2225
2222
trait = getBlanketImplementationTypeParam ( impl ) .resolveBound ( i ) and
2226
- // Exclude traits that are "trivial" in the sense that they are known to
2227
- // not narrow things down very much.
2223
+ // Exclude traits that are known to not narrow things down very much.
2228
2224
not trait .getName ( ) .getText ( ) =
2229
2225
[
2230
- "Sized" , "Clone" , "Fn" , "FnOnce" , "FnMut" ,
2226
+ "Sized" , "Clone" ,
2231
2227
// The auto traits
2232
2228
"Send" , "Sync" , "Unpin" , "UnwindSafe" , "RefUnwindSafe"
2233
2229
]
@@ -2257,7 +2253,7 @@ private module BlanketImplementation {
2257
2253
f = impl .resolveTraitTy ( ) .getAssocItem ( name )
2258
2254
) and
2259
2255
// If the method is already available through one of the trait bounds on the
2260
- // type parameter (because they share a common trait ancestor) then ignore
2256
+ // type parameter (because they share a common ancestor trait ) then ignore
2261
2257
// it.
2262
2258
not getBlanketImplementationTypeParam ( impl ) .resolveABound ( ) .( TraitItemNode ) .getASuccessor ( name ) =
2263
2259
f
0 commit comments