@@ -257,59 +257,75 @@ private Type inferAnnotatedType(AstNode n, TypePath path) {
257257
258258/** Module for inferring certain type information. */
259259private module CertainTypeInference {
260- /**
261- * Holds if `ce` is a call where we can infer the type with certainty and if
262- * `f` is the target of the call and `p` the path invoked by the call.
263- *
264- * Necessary conditions for this are:
265- * - We are certain of the call target (i.e., the call target can not depend on type information).
266- * - The declared type of the function does not contain any generics that we
267- * need to infer.
268- * - The call does not contain any arguments, as arguments in calls are coercion sites.
269- *
270- * The current requirements are made to allow for call to `new` functions such
271- * as `Vec<Foo>::new()` but not much more.
272- */
273- predicate certainCallExprTarget ( CallExpr ce , Function f , Path p ) {
260+ // /**
261+ // * Holds if `ce` is a call where we can infer the type with certainty and if
262+ // * `f` is the target of the call and `p` the path invoked by the call.
263+ // *
264+ // * Necessary conditions for this are:
265+ // * - We are certain of the call target (i.e., the call target can not depend on type information).
266+ // * - The declared type of the function does not contain any generics that we
267+ // * need to infer.
268+ // * - The call does not contain any arguments, as arguments in calls are coercion sites.
269+ // *
270+ // * The current requirements are made to allow for call to `new` functions such
271+ // * as `Vec<Foo>::new()` but not much more.
272+ // */
273+ // predicate certainCallExprTarget(CallExpr ce, Function f, Path p) {
274+ // p = CallExprImpl::getFunctionPath(ce) and
275+ // f = resolvePath(p) and
276+ // // The function is not in a trait
277+ // not any(TraitItemNode t).getAnAssocItem() = f and
278+ // // The function is not in a trait implementation
279+ // not any(ImplItemNode impl | impl.(Impl).hasTrait()).getAnAssocItem() = f and
280+ // // The function does not have parameters.
281+ // not f.getParamList().hasSelfParam() and
282+ // f.getParamList().getNumberOfParams() = 0 and
283+ // // The function is not async.
284+ // not f.isAsync() and
285+ // // For now, exclude functions in macro expansions.
286+ // not ce.isInMacroExpansion() and
287+ // // The function has no type parameters.
288+ // not f.hasGenericParamList() and
289+ // // The function does not have `impl` types among its parameters (these are type parameters).
290+ // not any(ImplTraitTypeRepr itt | not itt.isInReturnPos()).getFunction() = f and
291+ // (
292+ // not exists(ImplItemNode impl | impl.getAnAssocItem() = f)
293+ // or
294+ // // If the function is in an impl then the impl block has no type
295+ // // parameters or all the type parameters are given explicitly.
296+ // exists(ImplItemNode impl | impl.getAnAssocItem() = f |
297+ // not impl.(Impl).hasGenericParamList() or
298+ // impl.(Impl).getGenericParamList().getNumberOfGenericParams() =
299+ // p.getQualifier().getSegment().getGenericArgList().getNumberOfGenericArgs()
300+ // )
301+ // )
302+ // }
303+ pragma [ nomagic]
304+ private predicate callResolvesTo ( CallExpr ce , Path p , Function f ) {
274305 p = CallExprImpl:: getFunctionPath ( ce ) and
275- f = resolvePath ( p ) and
276- // The function is not in a trait
277- not any ( TraitItemNode t ) .getAnAssocItem ( ) = f and
278- // The function is not in a trait implementation
279- not any ( ImplItemNode impl | impl .( Impl ) .hasTrait ( ) ) .getAnAssocItem ( ) = f and
280- // The function does not have parameters.
281- not f .getParamList ( ) .hasSelfParam ( ) and
282- f .getParamList ( ) .getNumberOfParams ( ) = 0 and
283- // The function is not async.
284- not f .isAsync ( ) and
285- // For now, exclude functions in macro expansions.
286- not ce .isInMacroExpansion ( ) and
287- // The function has no type parameters.
288- not f .hasGenericParamList ( ) and
289- // The function does not have `impl` types among its parameters (these are type parameters).
290- not any ( ImplTraitTypeRepr itt | not itt .isInReturnPos ( ) ) .getFunction ( ) = f and
291- (
292- not exists ( ImplItemNode impl | impl .getAnAssocItem ( ) = f )
293- or
294- // If the function is in an impl then the impl block has no type
295- // parameters or all the type parameters are given explicitly.
296- exists ( ImplItemNode impl | impl .getAnAssocItem ( ) = f |
297- not impl .( Impl ) .hasGenericParamList ( ) or
298- impl .( Impl ) .getGenericParamList ( ) .getNumberOfGenericParams ( ) =
299- p .getQualifier ( ) .getSegment ( ) .getGenericArgList ( ) .getNumberOfGenericArgs ( )
300- )
301- )
306+ f = resolvePath ( p )
307+ }
308+
309+ pragma [ nomagic]
310+ private Type getCallExprType ( CallExpr ce , Path p , Function f , TypePath tp ) {
311+ callResolvesTo ( ce , p , f ) and
312+ result = f .( CallExprBaseMatchingInput:: FunctionDecl ) .getReturnType ( tp )
313+ }
314+
315+ pragma [ nomagic]
316+ private Type getCertainCallExprType ( CallExpr ce , Path p , TypePath tp ) {
317+ forex ( Function f | callResolvesTo ( ce , p , f ) | result = getCallExprType ( ce , p , f , tp ) )
302318 }
303319
304320 private ImplItemNode getFunctionImpl ( FunctionItemNode f ) { result .getAnAssocItem ( ) = f }
305321
306322 Type inferCertainCallExprType ( CallExpr ce , TypePath path ) {
307323 exists ( Function f , Type ty , TypePath prefix , Path p |
308- certainCallExprTarget ( ce , f , p ) and
309- ty = f .getRetType ( ) .getTypeRepr ( ) .( TypeMention ) .resolveTypeAt ( prefix )
324+ ty = getCertainCallExprType ( ce , p , prefix )
310325 |
311- if ty . ( TypeParamTypeParameter ) . getTypeParam ( ) = getFunctionImpl ( f ) . getTypeParam ( _ )
326+ if ty instanceof TypeParameter
312327 then
328+ ty .( TypeParamTypeParameter ) .getTypeParam ( ) = getFunctionImpl ( f ) .getTypeParam ( _) and
313329 exists ( TypePath pathToTp , TypePath suffix |
314330 // For type parameters of the `impl` block we must resolve their
315331 // instantiation from the path. For instance, for `impl<A> for Foo<A>`
@@ -878,7 +894,7 @@ private module CallExprBaseMatchingInput implements MatchingInputSig {
878894 }
879895 }
880896
881- private class FunctionDecl extends Declaration , Function {
897+ additional class FunctionDecl extends Declaration , Function {
882898 override TypeParameter getTypeParameter ( TypeParameterPosition ppos ) {
883899 typeParamMatchPosition ( this .getGenericParamList ( ) .getATypeParam ( ) , result , ppos )
884900 or
@@ -980,8 +996,7 @@ private module CallExprBaseMatchingInput implements MatchingInputSig {
980996 }
981997
982998 final class Access extends Call {
983- Access ( ) { not CertainTypeInference:: certainCallExprTarget ( this , _, _) }
984-
999+ // Access() { not CertainTypeInference::certainCallExprTarget(this, _, _) }
9851000 pragma [ nomagic]
9861001 Type getTypeArgument ( TypeArgumentPosition apos , TypePath path ) {
9871002 exists ( TypeMention arg | result = arg .resolveTypeAt ( path ) |
0 commit comments