@@ -889,8 +889,9 @@ private predicate isComplexRootStripped(TypePath path, Type type) {
889889 * T1, &T1, &mut T1, ..., Tn, &Tn, &mut Tn
890890 * ```
891891 *
892- * we recursively build up the list, only adding a new candidate receiver type to the list
893- * when we can rule out that the method cannot be found for the current candidate:
892+ * we recursively compute a set of candidates, only adding a new candidate receiver type
893+ * to the set when we can rule out that the method cannot be found for the current
894+ * candidate:
894895 *
895896 * ```text
896897 * forall method:
@@ -1214,7 +1215,7 @@ private module MethodResolution {
12141215 * as long as the method cannot be resolved in an earlier candidate type, and possibly
12151216 * applying a borrow at the end.
12161217 *
1217- * The string `derefChainBorrow` encodes the sequences of dereferences and whether a
1218+ * The string `derefChainBorrow` encodes the sequence of dereferences and whether a
12181219 * borrow has been applied.
12191220 *
12201221 * [1]: https://doc.rust-lang.org/reference/expressions/method-call-expr.html#r-expr.method.candidate-receivers
@@ -1302,14 +1303,14 @@ private module MethodResolution {
13021303 private class MethodCallCallExpr extends MethodCall , CallExpr {
13031304 MethodCallCallExpr ( ) {
13041305 exists ( getCallExprPathQualifier ( this ) ) and
1305- // even if a function cannot be resolved by path resolution, it may still
1306- // be possible to resolve a blanket implementation
1306+ // even if a method cannot be resolved by path resolution, it may still
1307+ // be possible to resolve a blanket implementation (so not `forex`)
13071308 forall ( ItemNode i | i = CallExprImpl:: getResolvedFunction ( this ) | i instanceof Method )
13081309 }
13091310
13101311 /**
13111312 * Holds if this call has a type qualifier, and we are able to resolve,
1312- * using path resolution, the function to a member of `impl`.
1313+ * using path resolution, the method to a member of `impl`.
13131314 *
13141315 * When this is the case, we still want to check that the type qualifier
13151316 * is an instance of the type being implemented, which is done in
@@ -1557,8 +1558,10 @@ private module MethodResolution {
15571558 ArgIsInstantiationOf< MethodCallCand , ReceiverIsInstantiationOfSelfParamInput > ;
15581559
15591560 /**
1560- * A configuration for matching the type qualifier of a function call against
1561- * the type being implemented in an `impl` block.
1561+ * A configuration for matching the type qualifier of a method call
1562+ * against the type being implemented in an `impl` block. For example,
1563+ * in `Q::m(x)`, we check that the type of `Q` is an instance of the
1564+ * type being implemented.
15621565 */
15631566 private module TypeQualifierIsInstantiationOfImplSelfInput implements
15641567 IsInstantiationOfInputSig< MethodCallCallExpr , TypeMentionTypeTree >
@@ -1897,91 +1900,11 @@ private module NonMethodResolution {
18971900
18981901 private module BlanketTraitIsVisible = TraitIsVisible< blanketCallTraitCandidate / 2 > ;
18991902
1900- private Type getTypeAt ( NonMethodCall fc , FunctionTypePosition pos , TypePath path ) {
1901- result = inferType ( fc .getNodeAt ( pos ) , path )
1902- }
1903-
1904- pragma [ nomagic]
1905- private predicate functionCallBlanketCandidate (
1906- NonMethodCall fc , NonMethodFunction f , ImplItemNode impl , FunctionTypePosition pos ,
1907- TypePath blanketPath , TypeParam blanketTypeParam
1908- ) {
1909- exists ( string name , int arity , Trait trait , AssocFunctionType t |
1910- fc .hasNameAndArity ( name , arity ) and
1911- exists ( getTypeAt ( fc , pos , blanketPath ) ) and
1912- functionInfoBlanketRelevantPos ( f , name , arity , impl , trait , pos , t , blanketPath ,
1913- blanketTypeParam ) and
1914- BlanketTraitIsVisible:: traitIsVisible ( fc , trait )
1915- )
1916- }
1917-
1918- private newtype TCallAndPos =
1919- MkCallAndPos ( NonMethodCall fc , FunctionTypePosition pos ) {
1920- functionCallBlanketCandidate ( fc , _, _, pos , _, _)
1921- }
1922-
1923- /** A call tagged with a position. */
1924- private class CallAndPos extends MkCallAndPos {
1925- NonMethodCall fc ;
1926- FunctionTypePosition pos ;
1927-
1928- CallAndPos ( ) { this = MkCallAndPos ( fc , pos ) }
1929-
1930- Location getLocation ( ) { result = fc .getLocation ( ) }
1931-
1932- Type getTypeAt ( TypePath path ) { result = getTypeAt ( fc , pos , path ) }
1933-
1934- string toString ( ) { result = fc .toString ( ) + " [arg " + pos + "]" }
1935- }
1936-
1937- private module ArgSatisfiesBlanketConstraintInput implements
1938- BlanketImplementation:: SatisfiesBlanketConstraintInputSig< CallAndPos >
1939- {
1940- pragma [ nomagic]
1941- predicate hasBlanketCandidate (
1942- CallAndPos fcp , ImplItemNode impl , TypePath blanketPath , TypeParam blanketTypeParam
1943- ) {
1944- exists ( NonMethodCall fc , FunctionTypePosition pos |
1945- fcp = MkCallAndPos ( fc , pos ) and
1946- functionCallBlanketCandidate ( fc , _, impl , pos , blanketPath , blanketTypeParam )
1947- )
1948- }
1949- }
1950-
1951- private module ArgSatisfiesBlanketConstraint =
1952- BlanketImplementation:: SatisfiesBlanketConstraint< CallAndPos , ArgSatisfiesBlanketConstraintInput > ;
1953-
1954- /**
1955- * A configuration for matching the type of an argument against the type of
1956- * a parameter that mentions a satisfied blanket type parameter.
1957- */
1958- private module ArgIsInstantiationOfBlanketParamInput implements
1959- IsInstantiationOfInputSig< CallAndPos , AssocFunctionType >
1960- {
1961- pragma [ nomagic]
1962- predicate potentialInstantiationOf (
1963- CallAndPos fcp , TypeAbstraction abs , AssocFunctionType constraint
1964- ) {
1965- exists ( FunctionTypePosition pos |
1966- ArgSatisfiesBlanketConstraint:: satisfiesBlanketConstraint ( fcp , abs ) and
1967- fcp = MkCallAndPos ( _, pos ) and
1968- functionInfoBlanketRelevantPos ( _, _, _, abs , _, pos , constraint , _, _)
1969- )
1970- }
1971-
1972- predicate relevantTypeMention ( AssocFunctionType constraint ) {
1973- functionInfoBlanketRelevantPos ( _, _, _, _, _, _, constraint , _, _)
1974- }
1975- }
1976-
1977- private module ArgIsInstantiationOfBlanketParam =
1978- ArgIsInstantiationOf< CallAndPos , ArgIsInstantiationOfBlanketParamInput > ;
1979-
19801903 /** A non-method call, `f(x)`. */
19811904 final class NonMethodCall extends CallExpr {
19821905 NonMethodCall ( ) {
19831906 // even if a function cannot be resolved by path resolution, it may still
1984- // be possible to resolve a blanket implementation
1907+ // be possible to resolve a blanket implementation (so not `forex`)
19851908 forall ( Function f | f = CallExprImpl:: getResolvedFunction ( this ) |
19861909 f instanceof NonMethodFunction
19871910 )
@@ -2032,6 +1955,23 @@ private module NonMethodResolution {
20321955 result = this and pos .isReturn ( )
20331956 }
20341957
1958+ Type getTypeAt ( FunctionTypePosition pos , TypePath path ) {
1959+ result = inferType ( this .getNodeAt ( pos ) , path )
1960+ }
1961+
1962+ pragma [ nomagic]
1963+ predicate resolveCallTargetBlanketCandidate (
1964+ ImplItemNode impl , FunctionTypePosition pos , TypePath blanketPath , TypeParam blanketTypeParam
1965+ ) {
1966+ exists ( string name , int arity , Trait trait , AssocFunctionType t |
1967+ this .hasNameAndArity ( name , arity ) and
1968+ exists ( this .getTypeAt ( pos , blanketPath ) ) and
1969+ functionInfoBlanketRelevantPos ( _, name , arity , impl , trait , pos , t , blanketPath ,
1970+ blanketTypeParam ) and
1971+ BlanketTraitIsVisible:: traitIsVisible ( this , trait )
1972+ )
1973+ }
1974+
20351975 pragma [ nomagic]
20361976 predicate hasTraitResolved ( TraitItemNode trait , NonMethodFunction resolved ) {
20371977 resolved = this .getPathResolutionResolved ( ) and
@@ -2061,6 +2001,69 @@ private module NonMethodResolution {
20612001 }
20622002 }
20632003
2004+ private newtype TCallAndBlanketPos =
2005+ MkCallAndBlanketPos ( NonMethodCall fc , FunctionTypePosition pos ) {
2006+ fc .resolveCallTargetBlanketCandidate ( _, pos , _, _)
2007+ }
2008+
2009+ /** A call tagged with a position. */
2010+ private class CallAndBlanketPos extends MkCallAndBlanketPos {
2011+ NonMethodCall fc ;
2012+ FunctionTypePosition pos ;
2013+
2014+ CallAndBlanketPos ( ) { this = MkCallAndBlanketPos ( fc , pos ) }
2015+
2016+ Location getLocation ( ) { result = fc .getLocation ( ) }
2017+
2018+ Type getTypeAt ( TypePath path ) { result = fc .getTypeAt ( pos , path ) }
2019+
2020+ string toString ( ) { result = fc .toString ( ) + " [arg " + pos + "]" }
2021+ }
2022+
2023+ private module ArgSatisfiesBlanketConstraintInput implements
2024+ BlanketImplementation:: SatisfiesBlanketConstraintInputSig< CallAndBlanketPos >
2025+ {
2026+ pragma [ nomagic]
2027+ predicate hasBlanketCandidate (
2028+ CallAndBlanketPos fcp , ImplItemNode impl , TypePath blanketPath , TypeParam blanketTypeParam
2029+ ) {
2030+ exists ( NonMethodCall fc , FunctionTypePosition pos |
2031+ fcp = MkCallAndBlanketPos ( fc , pos ) and
2032+ fc .resolveCallTargetBlanketCandidate ( impl , pos , blanketPath , blanketTypeParam )
2033+ )
2034+ }
2035+ }
2036+
2037+ private module ArgSatisfiesBlanketConstraint =
2038+ BlanketImplementation:: SatisfiesBlanketConstraint< CallAndBlanketPos ,
2039+ ArgSatisfiesBlanketConstraintInput > ;
2040+
2041+ /**
2042+ * A configuration for matching the type of an argument against the type of
2043+ * a parameter that mentions a satisfied blanket type parameter.
2044+ */
2045+ private module ArgIsInstantiationOfBlanketParamInput implements
2046+ IsInstantiationOfInputSig< CallAndBlanketPos , AssocFunctionType >
2047+ {
2048+ pragma [ nomagic]
2049+ predicate potentialInstantiationOf (
2050+ CallAndBlanketPos fcp , TypeAbstraction abs , AssocFunctionType constraint
2051+ ) {
2052+ exists ( FunctionTypePosition pos |
2053+ ArgSatisfiesBlanketConstraint:: satisfiesBlanketConstraint ( fcp , abs ) and
2054+ fcp = MkCallAndBlanketPos ( _, pos ) and
2055+ functionInfoBlanketRelevantPos ( _, _, _, abs , _, pos , constraint , _, _)
2056+ )
2057+ }
2058+
2059+ predicate relevantTypeMention ( AssocFunctionType constraint ) {
2060+ functionInfoBlanketRelevantPos ( _, _, _, _, _, _, constraint , _, _)
2061+ }
2062+ }
2063+
2064+ private module ArgIsInstantiationOfBlanketParam =
2065+ ArgIsInstantiationOf< CallAndBlanketPos , ArgIsInstantiationOfBlanketParamInput > ;
2066+
20642067 private module NonMethodArgsAreInstantiationsOfInput implements ArgsAreInstantiationsOfInputSig {
20652068 predicate toCheck (
20662069 ImplOrTraitItemNode i , Function f , FunctionTypePosition pos , AssocFunctionType t
0 commit comments