@@ -2158,29 +2158,26 @@ private predicate methodCallHasImplCandidate(MethodCall mc, Impl impl) {
21582158}
21592159
21602160private module BlanketImplementation {
2161- /**
2162- * Gets the type parameter for which `impl` is a blanket implementation, if
2163- * any.
2164- */
2165- private TypeParamItemNode getBlanketImplementationTypeParam ( Impl impl ) {
2166- result = impl .( ImplItemNode ) .resolveSelfTy ( ) and
2167- result = impl .getGenericParamList ( ) .getAGenericParam ( ) and
2168- // This impl block is not superseded by the expansion of an attribute macro.
2169- not exists ( impl .getAttributeMacroExpansion ( ) )
2170- }
2171-
2172- predicate isBlanketImplementation ( Impl impl ) { exists ( getBlanketImplementationTypeParam ( impl ) ) }
2173-
2174- private Impl getPotentialDuplicated ( string fileName , string traitName , int arity , string tpName ) {
2175- tpName = getBlanketImplementationTypeParam ( result ) .getName ( ) and
2161+ private ImplItemNode getPotentialDuplicated (
2162+ string fileName , string traitName , int arity , string tpName
2163+ ) {
2164+ tpName = result .getBlanketImplementationTypeParam ( ) .getName ( ) and
21762165 fileName = result .getLocation ( ) .getFile ( ) .getBaseName ( ) and
21772166 traitName = result .( ImplItemNode ) .resolveTraitTy ( ) .getName ( ) and
21782167 arity = result .( ImplItemNode ) .resolveTraitTy ( ) .( Trait ) .getNumberOfGenericParams ( )
21792168 }
21802169
2170+ private predicate duplicatedImpl ( Impl impl1 , Impl impl2 ) {
2171+ exists ( string fileName , string traitName , int arity , string tpName |
2172+ impl1 = getPotentialDuplicated ( fileName , traitName , arity , tpName ) and
2173+ impl2 = getPotentialDuplicated ( fileName , traitName , arity , tpName ) and
2174+ impl1 .getLocation ( ) .getFile ( ) .getAbsolutePath ( ) <
2175+ impl2 .getLocation ( ) .getFile ( ) .getAbsolutePath ( )
2176+ )
2177+ }
2178+
21812179 /**
2182- * Holds if `impl1` and `impl2` are duplicates and `impl2` is strictly more
2183- * "canonical" than `impl1`.
2180+ * Holds if `impl` is a canonical blanket implementation.
21842181 *
21852182 * Libraries can often occur several times in the database for different
21862183 * library versions. This causes the same blanket implementations to exist
@@ -2189,40 +2186,18 @@ private module BlanketImplementation {
21892186 * We detect these duplicates based on some simple heuristics (same trait
21902187 * name, file name, etc.). For these duplicates we select the one with the
21912188 * greatest file name (which usually is also the one with the greatest library
2192- * version in the path)
2189+ * version in the path) as the "canonical" implementation.
21932190 */
2194- predicate duplicatedImpl ( Impl impl1 , Impl impl2 ) {
2195- exists ( string fileName , string traitName , int arity , string tpName |
2196- impl1 = getPotentialDuplicated ( fileName , traitName , arity , tpName ) and
2197- impl2 = getPotentialDuplicated ( fileName , traitName , arity , tpName ) and
2198- impl1 .getLocation ( ) .getFile ( ) .getAbsolutePath ( ) <
2199- impl2 .getLocation ( ) .getFile ( ) .getAbsolutePath ( )
2200- )
2191+ private predicate isCanonicalImpl ( Impl impl ) {
2192+ not duplicatedImpl ( impl , _) and impl .( ImplItemNode ) .isBlanketImplementation ( )
22012193 }
22022194
2203- predicate isCanonicalImpl ( Impl impl ) {
2204- not duplicatedImpl ( impl , _) and isBlanketImplementation ( impl )
2205- }
2206-
2207- Impl getCanonicalImpl ( Impl impl ) {
2208- result =
2209- max ( Impl impl0 , Location l |
2210- duplicatedImpl ( impl , impl0 ) and l = impl0 .getLocation ( )
2211- |
2212- impl0 order by l .getFile ( ) .getAbsolutePath ( ) , l .getStartLine ( )
2213- )
2214- or
2215- isCanonicalImpl ( impl ) and result = impl
2216- }
2217-
2218- predicate isCanonicalBlanketImplementation ( Impl impl ) { impl = getCanonicalImpl ( impl ) }
2219-
22202195 /**
2221- * Holds if `impl` is a blanket implementation for a type parameter and the type
2222- * parameter must implement `trait `.
2196+ * Holds if `impl` is a blanket implementation for a type parameter with trait
2197+ * bound `traitBound `.
22232198 */
2224- private predicate blanketImplementationTraitBound ( Impl impl , Trait t ) {
2225- t =
2199+ private predicate blanketImplementationTraitBound ( Impl impl , Trait traitBound ) {
2200+ traitBound =
22262201 min ( Trait trait , int i |
22272202 trait = getBlanketImplementationTypeParam ( impl ) .resolveBound ( i ) and
22282203 // Exclude traits that are known to not narrow things down very much.
@@ -2243,10 +2218,10 @@ private module BlanketImplementation {
22432218 * `arity`.
22442219 */
22452220 private predicate blanketImplementationMethod (
2246- ImplItemNode impl , Trait trait , string name , int arity , Function f
2221+ ImplItemNode impl , Trait traitBound , string name , int arity , Function f
22472222 ) {
2248- isCanonicalBlanketImplementation ( impl ) and
2249- blanketImplementationTraitBound ( impl , trait ) and
2223+ isCanonicalImpl ( impl ) and
2224+ blanketImplementationTraitBound ( impl , traitBound ) and
22502225 f .getParamList ( ) .hasSelfParam ( ) and
22512226 arity = f .getParamList ( ) .getNumberOfParams ( ) and
22522227 (
@@ -2258,48 +2233,48 @@ private module BlanketImplementation {
22582233 f = impl .resolveTraitTy ( ) .getAssocItem ( name )
22592234 ) and
22602235 // If the method is already available through one of the trait bounds on the
2261- // type parameter (because they share a common ancestor trait) then ignore
2236+ // type parameter (because they share a common super trait) then ignore
22622237 // it.
22632238 not getBlanketImplementationTypeParam ( impl ) .resolveABound ( ) .( TraitItemNode ) .getASuccessor ( name ) =
22642239 f
22652240 }
22662241
2267- predicate methodCallMatchesBlanketImpl ( MethodCall mc , Type t , Impl impl , Trait trait , Function f ) {
2242+ pragma [ nomagic]
2243+ predicate methodCallMatchesBlanketImpl (
2244+ MethodCall mc , Type t , ImplItemNode impl , Trait traitBound , Trait traitImpl , Function f
2245+ ) {
22682246 // Only check method calls where we have ruled out inherent method targets.
22692247 // Ideally we would also check if non-blanket method targets have been ruled
22702248 // out.
22712249 methodCallHasNoInherentTarget ( mc ) and
22722250 exists ( string name , int arity |
22732251 isMethodCall ( mc , t , name , arity ) and
2274- blanketImplementationMethod ( impl , trait , name , arity , f )
2275- )
2252+ blanketImplementationMethod ( impl , traitBound , name , arity , f )
2253+ ) and
2254+ traitImpl = impl .resolveTraitTy ( )
22762255 }
22772256
22782257 private predicate relevantTraitVisible ( Element mc , Trait trait ) {
2279- exists ( ImplItemNode impl |
2280- methodCallMatchesBlanketImpl ( mc , _, impl , _, _) and
2281- trait = impl .resolveTraitTy ( )
2282- )
2258+ methodCallMatchesBlanketImpl ( mc , _, _, _, trait , _)
22832259 }
22842260
22852261 module SatisfiesConstraintInput implements SatisfiesConstraintInputSig< MethodCall > {
22862262 pragma [ nomagic]
22872263 predicate relevantConstraint ( MethodCall mc , Type constraint ) {
2288- exists ( Trait trait , Trait trait2 , ImplItemNode impl |
2289- methodCallMatchesBlanketImpl ( mc , _, impl , trait , _) and
2290- TraitIsVisible< relevantTraitVisible / 2 > :: traitIsVisible ( mc , pragma [ only_bind_into ] ( trait2 ) ) and
2291- trait2 = pragma [ only_bind_into ] ( impl .resolveTraitTy ( ) ) and
2292- trait = constraint .( TraitType ) .getTrait ( )
2264+ exists ( Trait traitBound , Trait traitImpl |
2265+ methodCallMatchesBlanketImpl ( mc , _, _, traitBound , traitImpl , _) and
2266+ TraitIsVisible< relevantTraitVisible / 2 > :: traitIsVisible ( mc , traitImpl ) and
2267+ traitBound = constraint .( TraitType ) .getTrait ( )
22932268 )
22942269 }
22952270
22962271 predicate useUniversalConditions ( ) { none ( ) }
22972272 }
22982273
2299- predicate hasBlanketImpl ( MethodCall mc , Type t , Impl impl , Trait trait , Function f ) {
2274+ predicate hasBlanketImpl ( MethodCall mc , Type t , Impl impl , Trait traitBound , Function f ) {
23002275 SatisfiesConstraint< MethodCall , SatisfiesConstraintInput > :: satisfiesConstraintType ( mc ,
2301- TTrait ( trait ) , _, _) and
2302- methodCallMatchesBlanketImpl ( mc , t , impl , trait , f )
2276+ TTrait ( traitBound ) , _, _) and
2277+ methodCallMatchesBlanketImpl ( mc , t , impl , traitBound , _ , f )
23032278 }
23042279
23052280 pragma [ nomagic]
0 commit comments