Skip to content

Commit e41fbea

Browse files
committed
wip
1 parent 41ba295 commit e41fbea

File tree

1 file changed

+62
-47
lines changed

1 file changed

+62
-47
lines changed

rust/ql/lib/codeql/rust/internal/TypeInference.qll

Lines changed: 62 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -257,59 +257,75 @@ private Type inferAnnotatedType(AstNode n, TypePath path) {
257257

258258
/** Module for inferring certain type information. */
259259
private 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

Comments
 (0)