From 104ba0e2910c9571706747e5ababc1bfc4a4b8ba Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Mon, 27 Oct 2025 13:18:09 +0100 Subject: [PATCH 1/2] Rust: Fix bad join Before ``` Pipeline standard for TypeInference::MethodCallMatching::AccessConstraint::RelevantAccess.getTypeAt/1#dispred#e8abf748@ada3a07w was evaluated in 801 iterations totaling 31ms (delta sizes total: 182871). 50151 ~1% {4} r1 = SCAN TypeInference::MethodCallMatching::AccessConstraint::MkRelevantAccess#7a01048b#prev_delta OUTPUT In.0, In.2, In.3, In.4 39574 ~0% {5} | JOIN WITH `TypeInference::MethodCallMatchingInput::Access.getInferredNonSelfType/2#dispred#b181cb0a#prev` ON FIRST 2 OUTPUT Lhs.3, Rhs.3, _, Lhs.2, Rhs.2 {3} | REWRITE WITH Tmp.2 := "", Out.2 := InverseAppend(In.3,Tmp.2,In.4) KEEPING 3 36996 ~0% {3} | SCAN OUTPUT In.0, In.2, In.1 36102333 ~0% {4} r2 = SCAN TypeInference::MethodCallMatching::AccessConstraint::MkRelevantAccess#7a01048b#prev OUTPUT In.0, In.2, In.3, In.4 90175 ~1% {5} | JOIN WITH `TypeInference::MethodCallMatchingInput::Access.getInferredNonSelfType/2#dispred#b181cb0a#prev_delta` ON FIRST 2 OUTPUT Lhs.3, Rhs.3, _, Lhs.2, Rhs.2 {3} | REWRITE WITH Tmp.2 := "", Out.2 := InverseAppend(In.3,Tmp.2,In.4) KEEPING 3 65014 ~1% {3} | SCAN OUTPUT In.0, In.2, In.1 50151 ~1% {5} r3 = SCAN TypeInference::MethodCallMatching::AccessConstraint::MkRelevantAccess#7a01048b#prev_delta OUTPUT In.2, In.0, In.1, In.3, In.4 24208 ~1% {4} | JOIN WITH `FunctionType::FunctionPosition.isSelf/0#dispred#9e84d302` ON FIRST 1 OUTPUT Lhs.1, Lhs.2, Lhs.3, Lhs.4 95022 ~0% {9} | JOIN WITH `TypeInference::MethodCallMatchingInput::Access.getInferredSelfType/3#dispred#45b2f893#prev` ON FIRST 1 OUTPUT Lhs.2, Lhs.3, Rhs.2, Rhs.3, Rhs.4, _, Rhs.1, Lhs.1, _ {6} | REWRITE WITH Tmp.5 := ";", Tmp.5 := (In.6 ++ Tmp.5), Tmp.8 := "", Out.5 := InverseAppend(Tmp.5,Tmp.8,In.7) KEEPING 6 93919 ~1% {7} | SCAN OUTPUT In.0, In.1, In.2, In.3, In.4, In.5, _ {6} | REWRITE WITH NOT [NOT [Tmp.6 := "borrow", TEST InOut.5 = Tmp.6, Tmp.6 := true, TEST InOut.2 = Tmp.6], NOT [Tmp.6 := "", TEST InOut.5 = Tmp.6, Tmp.6 := true, TEST InOut.2 != Tmp.6]] KEEPING 6 81298 ~1% {5} | SCAN OUTPUT In.1, In.4, _, In.0, In.3 {3} | REWRITE WITH Tmp.2 := "", Out.2 := InverseAppend(In.3,Tmp.2,In.4) KEEPING 3 64110 ~1% {3} | SCAN OUTPUT In.0, In.2, In.1 36102333 ~0% {5} r4 = SCAN TypeInference::MethodCallMatching::AccessConstraint::MkRelevantAccess#7a01048b#prev OUTPUT In.2, In.0, In.1, In.3, In.4 17473531 ~0% {4} | JOIN WITH `FunctionType::FunctionPosition.isSelf/0#dispred#9e84d302` ON FIRST 1 OUTPUT Lhs.1, Lhs.2, Lhs.3, Lhs.4 47409 ~1% {9} | JOIN WITH `TypeInference::MethodCallMatchingInput::Access.getInferredSelfType/3#dispred#45b2f893#prev_delta` ON FIRST 1 OUTPUT Lhs.2, Lhs.3, Rhs.2, Rhs.3, Rhs.4, _, Rhs.1, Lhs.1, _ {6} | REWRITE WITH Tmp.5 := ";", Tmp.5 := (In.6 ++ Tmp.5), Tmp.8 := "", Out.5 := InverseAppend(Tmp.5,Tmp.8,In.7) KEEPING 6 29885 ~0% {7} | SCAN OUTPUT In.0, In.1, In.2, In.3, In.4, In.5, _ {6} | REWRITE WITH NOT [NOT [Tmp.6 := "borrow", TEST InOut.5 = Tmp.6, Tmp.6 := true, TEST InOut.2 = Tmp.6], NOT [Tmp.6 := "", TEST InOut.5 = Tmp.6, Tmp.6 := true, TEST InOut.2 != Tmp.6]] KEEPING 6 16952 ~1% {5} | SCAN OUTPUT In.1, In.4, _, In.0, In.3 {3} | REWRITE WITH Tmp.2 := "", Out.2 := InverseAppend(In.3,Tmp.2,In.4) KEEPING 3 16829 ~0% {3} | SCAN OUTPUT In.0, In.2, In.1 182949 ~1% {3} r5 = r1 UNION r2 UNION r3 UNION r4 182949 ~1% {3} | AND NOT `TypeInference::MethodCallMatching::AccessConstraint::RelevantAccess.getTypeAt/1#dispred#e8abf748#prev`(FIRST 3) return r5 ``` After ``` Pipeline standard for TypeInference::MethodCallMatching::AccessConstraint::RelevantAccess.getTypeAt/1#dispred#e8abf748@31ee547w was evaluated in 801 iterations totaling 19ms (delta sizes total: 182946). 81298 ~0% {5} r1 = JOIN TypeInference::MethodCallMatching::AccessConstraint::MkRelevantAccess#7a01048b#prev_delta WITH `TypeInference::MethodCallMatchingInput::Access.getInferredSelfType/3#dispred#45b2f893#prev` ON FIRST 3 OUTPUT Lhs.4, Rhs.4, _, Lhs.3, Rhs.3 {3} | REWRITE WITH Tmp.2 := "", Out.2 := InverseAppend(In.3,Tmp.2,In.4) KEEPING 3 64110 ~1% {3} | SCAN OUTPUT In.0, In.2, In.1 39574 ~0% {5} r2 = JOIN TypeInference::MethodCallMatching::AccessConstraint::MkRelevantAccess#7a01048b#prev_delta WITH `TypeInference::MethodCallMatchingInput::Access.getInferredNonSelfType/2#dispred#b181cb0a#prev` ON FIRST 2 OUTPUT Lhs.4, Rhs.3, _, Lhs.3, Rhs.2 {3} | REWRITE WITH Tmp.2 := "", Out.2 := InverseAppend(In.3,Tmp.2,In.4) KEEPING 3 36996 ~0% {3} | SCAN OUTPUT In.0, In.2, In.1 16952 ~0% {5} r3 = JOIN TypeInference::MethodCallMatching::AccessConstraint::MkRelevantAccess#7a01048b#prev WITH `TypeInference::MethodCallMatchingInput::Access.getInferredSelfType/3#dispred#45b2f893#prev_delta` ON FIRST 3 OUTPUT Lhs.4, Rhs.4, _, Lhs.3, Rhs.3 {3} | REWRITE WITH Tmp.2 := "", Out.2 := InverseAppend(In.3,Tmp.2,In.4) KEEPING 3 16829 ~0% {3} | SCAN OUTPUT In.0, In.2, In.1 90175 ~0% {5} r4 = JOIN TypeInference::MethodCallMatching::AccessConstraint::MkRelevantAccess#7a01048b#prev WITH `TypeInference::MethodCallMatchingInput::Access.getInferredNonSelfType/2#dispred#b181cb0a#prev_delta` ON FIRST 2 OUTPUT Lhs.4, Rhs.3, _, Lhs.3, Rhs.2 {3} | REWRITE WITH Tmp.2 := "", Out.2 := InverseAppend(In.3,Tmp.2,In.4) KEEPING 3 65014 ~0% {3} | SCAN OUTPUT In.0, In.2, In.1 182949 ~1% {3} r5 = r1 UNION r2 UNION r3 UNION r4 182949 ~1% {3} | AND NOT `TypeInference::MethodCallMatching::AccessConstraint::RelevantAccess.getTypeAt/1#dispred#e8abf748#prev`(FIRST 3) return r5 ``` --- rust/ql/lib/codeql/rust/internal/TypeInference.qll | 14 +++++++------- .../typeinference/internal/TypeInference.qll | 8 ++++---- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/rust/ql/lib/codeql/rust/internal/TypeInference.qll b/rust/ql/lib/codeql/rust/internal/TypeInference.qll index bcc18342c007..15daf6d2f179 100644 --- a/rust/ql/lib/codeql/rust/internal/TypeInference.qll +++ b/rust/ql/lib/codeql/rust/internal/TypeInference.qll @@ -1812,8 +1812,12 @@ private module MethodCallMatchingInput implements MatchingWithEnvironmentInputSi } pragma[nomagic] - private Type getInferredSelfType(string derefChain, boolean borrow, TypePath path) { - result = this.getACandidateReceiverTypeAt(derefChain, borrow, path) + private Type getInferredSelfType(AccessPosition apos, string derefChainBorrow, TypePath path) { + exists(string derefChain, boolean borrow | + result = this.getACandidateReceiverTypeAt(derefChain, borrow, path) and + derefChainBorrow = encodeDerefChainBorrow(derefChain, borrow) and + apos.isSelf() + ) } pragma[nomagic] @@ -1839,11 +1843,7 @@ private module MethodCallMatchingInput implements MatchingWithEnvironmentInputSi bindingset[derefChainBorrow] Type getInferredType(string derefChainBorrow, AccessPosition apos, TypePath path) { - exists(string derefChain, boolean borrow | - derefChainBorrow = encodeDerefChainBorrow(derefChain, borrow) and - apos.isSelf() and - result = this.getInferredSelfType(derefChain, borrow, path) - ) + result = this.getInferredSelfType(apos, derefChainBorrow, path) or result = this.getInferredNonSelfType(apos, path) } diff --git a/shared/typeinference/codeql/typeinference/internal/TypeInference.qll b/shared/typeinference/codeql/typeinference/internal/TypeInference.qll index ff9ccf3c192b..7df7f26d9fa5 100644 --- a/shared/typeinference/codeql/typeinference/internal/TypeInference.qll +++ b/shared/typeinference/codeql/typeinference/internal/TypeInference.qll @@ -1269,7 +1269,7 @@ module Make1 Input1> { } private newtype TRelevantAccess = - MkRelevantAccess(Access a, AccessEnvironment e, AccessPosition apos, TypePath path) { + MkRelevantAccess(Access a, AccessPosition apos, AccessEnvironment e, TypePath path) { relevantAccessConstraint(a, e, _, apos, path, _) } @@ -1279,11 +1279,11 @@ module Make1 Input1> { */ private class RelevantAccess extends MkRelevantAccess { Access a; - AccessEnvironment e; AccessPosition apos; + AccessEnvironment e; TypePath path; - RelevantAccess() { this = MkRelevantAccess(a, e, apos, path) } + RelevantAccess() { this = MkRelevantAccess(a, apos, e, path) } Type getTypeAt(TypePath suffix) { result = a.getInferredType(e, apos, path.appendInverse(suffix)) @@ -1314,7 +1314,7 @@ module Make1 Input1> { Type constraint, TypePath path, Type t ) { exists(RelevantAccess ra | - ra = MkRelevantAccess(a, e, apos, prefix) and + ra = MkRelevantAccess(a, apos, e, prefix) and SatisfiesConstraint::satisfiesConstraintType(ra, constraint, path, t) and constraint = ra.getConstraint(target) From b3bbe78974a9a61a6fc3c2f12b4fea25c01c28da Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Mon, 27 Oct 2025 13:21:41 +0100 Subject: [PATCH 2/2] Rust: Fix bad join Before ``` Pipeline standard for TypeInference::MethodCallMatching::directTypeMatch/6#f0fb0b61@31ee5u2w was evaluated in 821 iterations totaling 1057ms (delta sizes total: 689971). 416937 ~1% {6} r1 = SCAN `TypeInference::MethodCallMatching::directTypeMatch0/6#dfcc7717#prev_delta` OUTPUT In.0, In.3, In.1, In.2, In.4, In.5 222757 ~2% {8} r2 = JOIN r1 WITH `TypeInference::MethodCallMatchingInput::Access.getInferredNonSelfType/2#dispred#b181cb0a#prev` ON FIRST 2 OUTPUT Lhs.0, Lhs.2, Lhs.3, Lhs.5, Rhs.3, _, Lhs.4, Rhs.2 {6} | REWRITE WITH Tmp.5 := "", Out.5 := InverseAppend(In.6,Tmp.5,In.7) KEEPING 6 164360 ~3% {6} | SCAN OUTPUT In.0, In.1, In.2, In.5, In.4, In.3 315350783 ~1% {6} r3 = SCAN `TypeInference::MethodCallMatching::directTypeMatch0/6#dfcc7717#prev` OUTPUT In.0, In.3, In.1, In.2, In.4, In.5 593815 ~1% {8} r4 = JOIN r3 WITH `TypeInference::MethodCallMatchingInput::Access.getInferredNonSelfType/2#dispred#b181cb0a#prev_delta` ON FIRST 2 OUTPUT Lhs.0, Lhs.2, Lhs.3, Lhs.5, Rhs.3, _, Lhs.4, Rhs.2 {6} | REWRITE WITH Tmp.5 := "", Out.5 := InverseAppend(In.6,Tmp.5,In.7) KEEPING 6 342226 ~1% {6} | SCAN OUTPUT In.0, In.1, In.2, In.5, In.4, In.3 826517 ~0% {8} r5 = JOIN r1 WITH `TypeInference::MethodCallMatchingInput::Access.getInferredSelfType/3#dispred#45b2f893#prev` ON FIRST 3 OUTPUT Lhs.0, Lhs.2, Lhs.3, Lhs.5, Rhs.4, _, Lhs.4, Rhs.3 {6} | REWRITE WITH Tmp.5 := "", Out.5 := InverseAppend(In.6,Tmp.5,In.7) KEEPING 6 345294 ~1% {6} | SCAN OUTPUT In.0, In.1, In.2, In.5, In.4, In.3 73715 ~0% {8} r6 = JOIN r3 WITH `TypeInference::MethodCallMatchingInput::Access.getInferredSelfType/3#dispred#45b2f893#prev_delta` ON FIRST 3 OUTPUT Lhs.0, Lhs.2, Lhs.3, Lhs.5, Rhs.4, _, Lhs.4, Rhs.3 {6} | REWRITE WITH Tmp.5 := "", Out.5 := InverseAppend(In.6,Tmp.5,In.7) KEEPING 6 47802 ~1% {6} | SCAN OUTPUT In.0, In.1, In.2, In.5, In.4, In.3 899682 ~5% {6} r7 = r2 UNION r4 UNION r5 UNION r6 711040 ~6% {6} | AND NOT `TypeInference::MethodCallMatching::directTypeMatch/6#f0fb0b61#prev`(FIRST 6) return r7 ``` After ``` Pipeline standard for TypeInference::MethodCallMatching::directTypeMatch/6#f0fb0b61@ad458u2w was evaluated in 821 iterations totaling 374ms (delta sizes total: 691168). 222757 ~2% {8} r1 = JOIN `TypeInference::MethodCallMatching::directTypeMatch0/6#dfcc7717#prev_delta` WITH `TypeInference::MethodCallMatchingInput::Access.getInferredNonSelfType/2#dispred#b181cb0a#prev` ON FIRST 2 OUTPUT Lhs.0, Lhs.2, Lhs.3, Lhs.5, Rhs.3, _, Lhs.4, Rhs.2 {6} | REWRITE WITH Tmp.5 := "", Out.5 := InverseAppend(In.6,Tmp.5,In.7) KEEPING 6 164360 ~3% {6} | SCAN OUTPUT In.0, In.1, In.2, In.5, In.4, In.3 593815 ~1% {8} r2 = JOIN `TypeInference::MethodCallMatching::directTypeMatch0/6#dfcc7717#prev` WITH `TypeInference::MethodCallMatchingInput::Access.getInferredNonSelfType/2#dispred#b181cb0a#prev_delta` ON FIRST 2 OUTPUT Lhs.0, Lhs.2, Lhs.3, Lhs.5, Rhs.3, _, Lhs.4, Rhs.2 {6} | REWRITE WITH Tmp.5 := "", Out.5 := InverseAppend(In.6,Tmp.5,In.7) KEEPING 6 342226 ~1% {6} | SCAN OUTPUT In.0, In.1, In.2, In.5, In.4, In.3 826517 ~0% {8} r3 = JOIN `TypeInference::MethodCallMatching::directTypeMatch0/6#dfcc7717#prev_delta` WITH `TypeInference::MethodCallMatchingInput::Access.getInferredSelfType/3#dispred#45b2f893#prev` ON FIRST 3 OUTPUT Lhs.0, Lhs.2, Lhs.3, Lhs.5, Rhs.4, _, Lhs.4, Rhs.3 {6} | REWRITE WITH Tmp.5 := "", Out.5 := InverseAppend(In.6,Tmp.5,In.7) KEEPING 6 345294 ~1% {6} | SCAN OUTPUT In.0, In.1, In.2, In.5, In.4, In.3 73715 ~0% {8} r4 = JOIN `TypeInference::MethodCallMatching::directTypeMatch0/6#dfcc7717#prev` WITH `TypeInference::MethodCallMatchingInput::Access.getInferredSelfType/3#dispred#45b2f893#prev_delta` ON FIRST 3 OUTPUT Lhs.0, Lhs.2, Lhs.3, Lhs.5, Rhs.4, _, Lhs.4, Rhs.3 {6} | REWRITE WITH Tmp.5 := "", Out.5 := InverseAppend(In.6,Tmp.5,In.7) KEEPING 6 47802 ~1% {6} | SCAN OUTPUT In.0, In.1, In.2, In.5, In.4, In.3 899682 ~5% {6} r5 = r1 UNION r2 UNION r3 UNION r4 711095 ~6% {6} | AND NOT `TypeInference::MethodCallMatching::directTypeMatch/6#f0fb0b61#prev`(FIRST 6) return r5 ``` --- .../codeql/typeinference/internal/TypeInference.qll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shared/typeinference/codeql/typeinference/internal/TypeInference.qll b/shared/typeinference/codeql/typeinference/internal/TypeInference.qll index 7df7f26d9fa5..0b259df92116 100644 --- a/shared/typeinference/codeql/typeinference/internal/TypeInference.qll +++ b/shared/typeinference/codeql/typeinference/internal/TypeInference.qll @@ -1160,7 +1160,7 @@ module Make1 Input1> { pragma[nomagic] private predicate directTypeMatch0( - Access a, AccessEnvironment e, Declaration target, DeclarationPosition dpos, + Access a, DeclarationPosition dpos, AccessEnvironment e, Declaration target, TypePath pathToTypeParam, TypeParameter tp ) { not exists(getTypeArgument(a, target, tp, _)) and @@ -1177,7 +1177,7 @@ module Make1 Input1> { Access a, AccessEnvironment e, Declaration target, TypePath path, Type t, TypeParameter tp ) { exists(AccessPosition apos, DeclarationPosition dpos, TypePath pathToTypeParam | - directTypeMatch0(a, e, target, dpos, pathToTypeParam, tp) and + directTypeMatch0(a, dpos, e, target, pathToTypeParam, tp) and accessDeclarationPositionMatch(apos, dpos) and t = a.getInferredType(e, apos, pathToTypeParam.appendInverse(path)) )