@@ -287,10 +287,12 @@ private module RankEdge<edgeSig/2 edge> implements RankedEdge {
287287}
288288
289289private signature module TypePropagation {
290- predicate candType ( TypeFlowNode n , RefType t ) ;
290+ class Typ ;
291+
292+ predicate candType ( TypeFlowNode n , Typ t ) ;
291293
292294 bindingset [ t]
293- predicate supportsType ( TypeFlowNode n , RefType t ) ;
295+ predicate supportsType ( TypeFlowNode n , Typ t ) ;
294296}
295297
296298/** Implements recursion through `forall` by way of edge ranking. */
@@ -300,7 +302,7 @@ private module ForAll<RankedEdge Edge, TypePropagation T> {
300302 * thus is a candidate bound for `n`.
301303 */
302304 pragma [ nomagic]
303- private predicate candJoinType ( TypeFlowNode n , RefType t ) {
305+ private predicate candJoinType ( TypeFlowNode n , T :: Typ t ) {
304306 exists ( TypeFlowNode mid |
305307 T:: candType ( mid , t ) and
306308 Edge:: edgeRank ( _, mid , n )
@@ -311,7 +313,7 @@ private module ForAll<RankedEdge Edge, TypePropagation T> {
311313 * Holds if `t` is a candidate bound for `n` that is also valid for data coming
312314 * through the edges into `n` ranked from `1` to `r`.
313315 */
314- private predicate flowJoin ( int r , TypeFlowNode n , RefType t ) {
316+ private predicate flowJoin ( int r , TypeFlowNode n , T :: Typ t ) {
315317 (
316318 r = 1 and candJoinType ( n , t )
317319 or
@@ -325,7 +327,7 @@ private module ForAll<RankedEdge Edge, TypePropagation T> {
325327 * coming through all the incoming edges, and therefore is a valid bound for
326328 * `n`.
327329 */
328- predicate flowJoin ( TypeFlowNode n , RefType t ) { flowJoin ( Edge:: lastRank ( n ) , n , t ) }
330+ predicate flowJoin ( TypeFlowNode n , T :: Typ t ) { flowJoin ( Edge:: lastRank ( n ) , n , t ) }
329331}
330332
331333module RankedJoinStep = RankEdge< joinStep / 2 > ;
@@ -342,6 +344,8 @@ private predicate exactTypeBase(TypeFlowNode n, RefType t) {
342344}
343345
344346private module ExactTypePropagation implements TypePropagation {
347+ class Typ = RefType ;
348+
345349 predicate candType = exactType / 2 ;
346350
347351 predicate supportsType = exactType / 2 ;
@@ -387,10 +391,10 @@ private predicate upcastCand(TypeFlowNode n, RefType t1, RefType t1e, RefType t2
387391private predicate unconstrained ( BoundedType t ) {
388392 t .( Wildcard ) .isUnconstrained ( )
389393 or
390- t .( BoundedType ) . getUpperBoundType ( ) instanceof TypeObject and
394+ t .getUpperBoundType ( ) instanceof TypeObject and
391395 not t .( Wildcard ) .hasLowerBound ( )
392396 or
393- unconstrained ( t .( BoundedType ) . getUpperBoundType ( ) )
397+ unconstrained ( t .getUpperBoundType ( ) )
394398 or
395399 unconstrained ( t .( Wildcard ) .getLowerBoundType ( ) )
396400}
@@ -537,6 +541,8 @@ private predicate typeFlowBase(TypeFlowNode n, RefType t) {
537541}
538542
539543private module TypeFlowPropagation implements TypePropagation {
544+ class Typ = RefType ;
545+
540546 predicate candType = typeFlow / 2 ;
541547
542548 bindingset [ t]
@@ -644,6 +650,17 @@ private predicate unionTypeFlowBaseCand(TypeFlowNode n, RefType t, boolean exact
644650 )
645651}
646652
653+ private module HasUnionTypePropagation implements TypePropagation {
654+ class Typ = Unit ;
655+
656+ predicate candType ( TypeFlowNode mid , Unit unit ) {
657+ exists ( unit ) and
658+ ( unionTypeFlowBaseCand ( mid , _, _) or hasUnionTypeFlow ( mid ) )
659+ }
660+
661+ predicate supportsType = candType / 2 ;
662+ }
663+
647664/**
648665 * Holds if all incoming type flow can be traced back to a
649666 * `unionTypeFlowBaseCand`, such that we can compute a union type bound for `n`.
@@ -652,15 +669,15 @@ private predicate unionTypeFlowBaseCand(TypeFlowNode n, RefType t, boolean exact
652669private predicate hasUnionTypeFlow ( TypeFlowNode n ) {
653670 not exactType ( n , _) and
654671 (
655- forex ( TypeFlowNode mid | joinStep ( mid , n ) |
656- unionTypeFlowBaseCand ( mid , _, _) or hasUnionTypeFlow ( mid )
657- )
672+ // Optimized version of
673+ // `forex(TypeFlowNode mid | joinStep(mid, n) | unionTypeFlowBaseCand(mid, _, _) or hasUnionTypeFlow(mid))`
674+ ForAll < RankedJoinStep , HasUnionTypePropagation > :: flowJoin ( n , _ )
658675 or
659676 exists ( TypeFlowNode scc |
660677 sccRepr ( n , scc ) and
661- forex ( TypeFlowNode mid | sccJoinStep ( mid , scc ) |
662- unionTypeFlowBaseCand ( mid , _, _) or hasUnionTypeFlow ( mid )
663- )
678+ // Optimized version of
679+ // `forex(TypeFlowNode mid | sccJoinStep(mid, scc) | unionTypeFlowBaseCand(mid, _, _) or hasUnionTypeFlow(mid))`
680+ ForAll < RankedSccJoinStep , HasUnionTypePropagation > :: flowJoin ( scc , _ )
664681 )
665682 or
666683 exists ( TypeFlowNode mid | step ( mid , n ) and hasUnionTypeFlow ( mid ) )
0 commit comments