@@ -263,10 +263,75 @@ predicate lambdaCallExpr(CallExprImpl::DynamicCallExpr call, LambdaCallKind kind
263263 exists ( kind )
264264}
265265
266+ // NOTE: We do not yet track type information, except for closures where
267+ // we use the closure itself to represent the unique type.
268+ final class DataFlowType extends TDataFlowType {
269+ Expr asClosureExpr ( ) { this = TClosureExprType ( result ) }
270+
271+ predicate isUnknownType ( ) { this = TUnknownType ( ) }
272+
273+ predicate isSourceContextParameterType ( ) { this = TSourceContextParameterType ( ) }
274+
275+ string toString ( ) {
276+ exists ( this .asClosureExpr ( ) ) and
277+ result = "... => .."
278+ or
279+ this .isUnknownType ( ) and
280+ result = ""
281+ or
282+ this .isSourceContextParameterType ( ) and
283+ result = "<source context parameter type>"
284+ }
285+ }
286+
287+ pragma [ nomagic]
288+ private predicate compatibleTypesLeft ( DataFlowType t1 , DataFlowType t2 ) {
289+ t1 .isUnknownType ( )
290+ or
291+ t1 .asClosureExpr ( ) = t2 .asClosureExpr ( )
292+ or
293+ t1 .isSourceContextParameterType ( ) and not exists ( t2 .asClosureExpr ( ) )
294+ }
295+
296+ predicate compatibleTypes ( DataFlowType t1 , DataFlowType t2 ) {
297+ compatibleTypesLeft ( t1 , t2 )
298+ or
299+ compatibleTypesLeft ( t2 , t1 )
300+ }
301+
302+ pragma [ nomagic]
303+ predicate typeStrongerThan ( DataFlowType t1 , DataFlowType t2 ) { exists ( t1 ) and t2 .isUnknownType ( ) }
304+
305+ DataFlowType getNodeType ( NodePublic node ) {
306+ result .asClosureExpr ( ) = node .asExpr ( )
307+ or
308+ result .asClosureExpr ( ) = node .( ClosureParameterNode ) .getCfgScope ( )
309+ or
310+ exists ( VariableCapture:: Flow:: SynthesizedCaptureNode scn |
311+ scn = node .( CaptureNode ) .getSynthesizedCaptureNode ( ) and
312+ if scn .isInstanceAccess ( )
313+ then result .asClosureExpr ( ) = scn .getEnclosingCallable ( )
314+ else result .isUnknownType ( )
315+ )
316+ or
317+ not lambdaCreationExpr ( node .asExpr ( ) ) and
318+ not node instanceof ClosureParameterNode and
319+ not node instanceof CaptureNode and
320+ result .isUnknownType ( )
321+ }
322+
266323// Defines a set of aliases needed for the `RustDataFlow` module
267324private module Aliases {
268325 class DataFlowCallableAlias = DataFlowCallable ;
269326
327+ class DataFlowTypeAlias = DataFlowType ;
328+
329+ predicate compatibleTypesAlias = compatibleTypes / 2 ;
330+
331+ predicate typeStrongerThanAlias = typeStrongerThan / 2 ;
332+
333+ predicate getNodeTypeAlias = getNodeType / 1 ;
334+
270335 class ReturnKindAlias = ReturnKind ;
271336
272337 class DataFlowCallAlias = DataFlowCall ;
@@ -398,8 +463,6 @@ module RustDataFlowGen<RustDataFlowInputSig Input> implements InputSig<Location>
398463 result = node .( Node:: Node ) .getEnclosingCallable ( )
399464 }
400465
401- DataFlowType getNodeType ( Node node ) { any ( ) }
402-
403466 predicate nodeIsHidden ( Node node ) {
404467 node instanceof SsaNode or
405468 node .( FlowSummaryNode ) .getSummaryNode ( ) .isHidden ( ) or
@@ -486,15 +549,15 @@ module RustDataFlowGen<RustDataFlowInputSig Input> implements InputSig<Location>
486549 */
487550 OutNode getAnOutNode ( DataFlowCall call , ReturnKind kind ) { call = result .getCall ( kind ) }
488551
489- // NOTE: For now we use the type `Unit` and do not benefit from type
490- // information in the data flow analysis.
491- final class DataFlowType extends Unit {
492- string toString ( ) { result = "" }
493- }
552+ class DataFlowType = DataFlowTypeAlias ;
494553
495- predicate compatibleTypes ( DataFlowType t1 , DataFlowType t2 ) { any ( ) }
554+ predicate compatibleTypes = compatibleTypesAlias / 2 ;
496555
497- predicate typeStrongerThan ( DataFlowType t1 , DataFlowType t2 ) { none ( ) }
556+ predicate typeStrongerThan = typeStrongerThanAlias / 2 ;
557+
558+ DataFlowType getSourceContextParameterNodeType ( ) { result .isSourceContextParameterType ( ) }
559+
560+ predicate getNodeType = getNodeTypeAlias / 1 ;
498561
499562 class Content = ContentAlias ;
500563
@@ -1110,6 +1173,12 @@ private module Cached {
11101173 TCfgScope ( CfgScope scope ) or
11111174 TSummarizedCallable ( SummarizedCallable c )
11121175
1176+ cached
1177+ newtype TDataFlowType =
1178+ TClosureExprType ( Expr e ) { lambdaCreationExpr ( e ) } or
1179+ TUnknownType ( ) or
1180+ TSourceContextParameterType ( )
1181+
11131182 /** This is the local flow predicate that is exposed. */
11141183 cached
11151184 predicate localFlowStepImpl ( Node nodeFrom , Node nodeTo ) {
0 commit comments