Rust: Avoid expensive regex calls

Before
```
Pipeline standard for TypeInference::AssocFunctionResolution::AssocFunctionCall.hasIncompatibleTarget/5#85c07422@d5eb7r0w was evaluated in 782 iterations totaling 13208ms (delta sizes total: 20187834).
            1464   ~2%    {7} r1 = JOIN `TypeInference::AssocFunctionResolution::SelfArgIsInstantiationOf::argIsInstantiationOf/6#aaa87ac9#prev_delta` WITH `TypeInference::AssocFunctionResolution::OverloadedCallArgsAreInstantiationsOf::argsAreNotInstantiationsOf/2#6a6070f7#prev` ON FIRST 2 OUTPUT Lhs.5, _, Lhs.0, Lhs.1, Lhs.2, Lhs.3, Lhs.4
            1464   ~0%    {7}    | REWRITE WITH Out.1 := ""
            1464   ~0%    {6}    | JOIN WITH `FunctionType::AssocFunctionType.getTypeAt/1#dispred#d4d46f61` ON FIRST 2 OUTPUT Lhs.2, Lhs.3, Lhs.4, Lhs.5, Lhs.6, Rhs.2

          173691   ~1%    {7} r2 = JOIN `TypeInference::AssocFunctionResolution::OverloadedCallArgsAreInstantiationsOf::argsAreNotInstantiationsOf/2#6a6070f7#prev_delta` WITH `TypeInference::AssocFunctionResolution::SelfArgIsInstantiationOf::argIsInstantiationOf/6#aaa87ac9#prev` ON FIRST 2 OUTPUT Rhs.5, _, Lhs.0, Lhs.1, Rhs.2, Rhs.3, Rhs.4
          173691   ~1%    {7}    | REWRITE WITH Out.1 := ""
          173691   ~1%    {6}    | JOIN WITH `FunctionType::AssocFunctionType.getTypeAt/1#dispred#d4d46f61` ON FIRST 2 OUTPUT Lhs.2, Lhs.3, Lhs.4, Lhs.5, Lhs.6, Rhs.2

        20022454   ~0%    {7} r3 = SCAN `TypeInference::AssocFunctionResolution::SelfArgIsInstantiationOf::argIsNotInstantiationOf/6#1b8e512e#prev_delta` OUTPUT In.0, In.1, In.2, In.3, In.4, In.5, _
        20022454   ~0%    {7}    | REWRITE WITH Out.6 := "^([0-9]+)\\..*$"
        20022175   ~2%    {9}    | JOIN WITH PRIMITIVE regexpCapture#bbff ON Lhs.5,Lhs.6
        20022175   ~2%    {10}    | SCAN OUTPUT In.0, In.1, In.2, In.3, In.4, In.5, In.6, In.7, In.8, _
                          {9}    | REWRITE WITH Tmp.9 := 1, TEST InOut.7 = Tmp.9 KEEPING 9
        20022175   ~1%    {7}    | SCAN OUTPUT In.8, In.0, In.1, In.2, In.3, In.4, In.5
        20022175   ~1%    {8}    | JOIN WITH `UnboundList::Make<Locations::Location,TypeInference::M1::UnboundListInput>::encode/1#47b2ec3f_10#join_rhs` ON FIRST 1 OUTPUT Rhs.1, Lhs.1, Lhs.2, Lhs.3, Lhs.4, Lhs.5, Lhs.6, Lhs.0
        20022175   ~0%    {10}    | JOIN WITH `Type::Type.getATypeParameter/0#dispred#ddf0e8ff_10#join_rhs` ON FIRST 1 OUTPUT Lhs.1, Lhs.2, Lhs.3, Lhs.4, Lhs.5, Rhs.1, _, Lhs.6, Lhs.7, _
                          {7}    | REWRITE WITH Tmp.6 := length(In.8), Tmp.9 := 1, Tmp.6 := (Tmp.6 + Tmp.9), Out.6 := suffix(In.7,Tmp.6) KEEPING 7
        20022175   ~0%    {6}    | SCAN OUTPUT In.0, In.1, In.2, In.3, In.4, In.5

        20197330   ~0%    {6} r4 = r1 UNION r2 UNION r3
        20187834   ~0%    {6}    | AND NOT `TypeInference::AssocFunctionResolution::AssocFunctionCall.hasIncompatibleTarget/5#85c07422#prev`(FIRST 6)
                          return r4
```

After
```
Pipeline standard for TypeInference::AssocFunctionResolution::AssocFunctionCall.hasIncompatibleTarget/5#85c07422@a58ce91w was evaluated in 537 iterations totaling 382ms (delta sizes total: 20033950).
        19862347   ~0%    {7} r1 = SCAN `TypeInference::AssocFunctionResolution::SelfArgIsInstantiationOf::argIsNotInstantiationOf/6#1b8e512e#prev_delta` OUTPUT In.5, _, In.0, In.1, In.2, In.3, In.4
        19862347   ~0%    {7}    | REWRITE WITH Out.1 := ""

          174684   ~1%    {7} r2 = SCAN `TypeInference::AssocFunctionResolution::AssocFunctionCall.hasIncompatibleArgsTarget/5#dispred#7d49b9f9#prev_delta` OUTPUT In.5, _, In.0, In.1, In.2, In.3, In.4
          174684   ~1%    {7}    | REWRITE WITH Out.1 := ""

        20037031   ~0%    {7} r3 = r1 UNION r2
        20037031   ~0%    {6}    | JOIN WITH `FunctionType::AssocFunctionType.getTypeAt/1#dispred#d4d46f61` ON FIRST 2 OUTPUT Lhs.2, Lhs.3, Lhs.4, Lhs.5, Lhs.6, Rhs.2
        20033950   ~0%    {6}    | AND NOT `TypeInference::AssocFunctionResolution::AssocFunctionCall.hasIncompatibleTarget/5#85c07422#prev`(FIRST 6)
                          return r3
```
This commit is contained in:
Tom Hvitved
2026-04-14 09:20:05 +02:00
parent 0db62b2e68
commit d69be77035

View File

@@ -1708,6 +1708,15 @@ private module AssocFunctionResolution {
predicate hasReceiverAtPos(FunctionPosition pos) { this.hasReceiver() and pos.asPosition() = 0 }
pragma[nomagic]
private predicate hasIncompatibleArgsTarget(
ImplOrTraitItemNode i, FunctionPosition selfPos, DerefChain derefChain, BorrowKind borrow,
AssocFunctionType selfType
) {
SelfArgIsInstantiationOf::argIsInstantiationOf(this, i, selfPos, derefChain, borrow, selfType) and
OverloadedCallArgsAreInstantiationsOf::argsAreNotInstantiationsOf(this, i)
}
/**
* Holds if the function inside `i` with matching name and arity can be ruled
* out as a target of this call, because the candidate receiver type represented
@@ -1722,16 +1731,11 @@ private module AssocFunctionResolution {
ImplOrTraitItemNode i, FunctionPosition selfPos, DerefChain derefChain, BorrowKind borrow,
Type root
) {
exists(TypePath path |
SelfArgIsInstantiationOf::argIsNotInstantiationOf(this, i, selfPos, derefChain, borrow, path) and
path.isCons(root.getATypeParameter(), _)
)
or
exists(AssocFunctionType selfType |
SelfArgIsInstantiationOf::argIsInstantiationOf(this, i, selfPos, derefChain, borrow,
selfType) and
OverloadedCallArgsAreInstantiationsOf::argsAreNotInstantiationsOf(this, i) and
root = selfType.getTypeAt(TypePath::nil())
exists(AssocFunctionType selfType | root = selfType.getTypeAt(TypePath::nil()) |
this.hasIncompatibleArgsTarget(i, selfPos, derefChain, borrow, selfType)
or
SelfArgIsInstantiationOf::argIsNotInstantiationOf(this, i, selfPos, derefChain, borrow,
selfType)
)
}
@@ -2608,9 +2612,13 @@ private module AssocFunctionResolution {
pragma[nomagic]
predicate argIsNotInstantiationOf(
AssocFunctionCall afc, ImplOrTraitItemNode i, FunctionPosition selfPos, DerefChain derefChain,
BorrowKind borrow, TypePath path
BorrowKind borrow, AssocFunctionType selfType
) {
argIsNotInstantiationOf(MkAssocFunctionCallCand(afc, selfPos, derefChain, borrow), i, _, path)
exists(TypePath path |
argIsNotInstantiationOf(MkAssocFunctionCallCand(afc, selfPos, derefChain, borrow), i,
selfType, path) and
not path.isEmpty()
)
}
pragma[nomagic]