Skip to content

Conversation

@hvitved
Copy link
Contributor

@hvitved hvitved commented Dec 17, 2025

Before

Evaluated relational algebra for predicate TypeInference::MethodResolution::MethodCall.getTrait/0#dispred#fc13ba6e@914858bt with tuple counts:
          153112   ~2%    {2} r1 = SCAN `Operation::Operation.isOverloaded/3#f0e64084` OUTPUT In.0, In.1
          153112   ~2%    {2}    | STREAM DEDUP

           18807   ~0%    {2} r2 = JOIN `TypeInference::getCallExprTraitQualifier/1#c084fe9f` WITH TypeInference::MethodResolution::MethodCallCallExpr#6eae461f ON FIRST 1 OUTPUT Lhs.0, Lhs.1

        65859035   ~3%    {3} r3 = JOIN `_IndexExpr::Generated::IndexExpr#9975e37a_TypeInference::MethodResolution::MethodCallIndexExpr.isInM__#shared` WITH Trait::Generated::Trait#ecf50173 CARTESIAN PRODUCT OUTPUT Rhs.0, _, Lhs.0
        65859035   ~0%    {3}    | REWRITE WITH Out.1 := "core::ops::index::Index"
           11191   ~0%    {2}    | JOIN WITH `Addressable::Addressable.getCanonicalPath/0#dispred#6044348f#bb` ON FIRST 2 OUTPUT Lhs.2, Lhs.0

             671   ~0%    {1} r4 = JOIN IndexExpr::Generated::IndexExpr#9975e37a WITH `TypeInference::MethodResolution::MethodCallIndexExpr.isInMutableContext/0#dispred#8c8ad425` ON FIRST 1 OUTPUT Lhs.0
         3948835   ~2%    {3}    | JOIN WITH Trait::Generated::Trait#ecf50173 CARTESIAN PRODUCT OUTPUT Rhs.0, _, Lhs.0
         3948835   ~2%    {3}    | REWRITE WITH Out.1 := "core::ops::index::IndexMut"
             671   ~1%    {2}    | JOIN WITH `Addressable::Addressable.getCanonicalPath/0#dispred#6044348f#bb` ON FIRST 2 OUTPUT Lhs.2, Lhs.0

          183781   ~0%    {2} r5 = r1 UNION r2 UNION r3 UNION r4
                          return r5

After

Evaluated relational algebra for predicate TypeInference::MethodResolution::MethodCall.getTrait/0#dispred#fc13ba6e@1b4a55e3 with tuple counts:
        153112   ~2%    {2} r1 = SCAN `Operation::Operation.isOverloaded/3#f0e64084` OUTPUT In.0, In.1
        153112   ~2%    {2}    | STREAM DEDUP

         11191   ~0%    {2} r2 = JOIN `_IndexExpr::Generated::IndexExpr#9975e37a_TypeInference::MethodResolution::MethodCallIndexExpr.isInM__#shared` WITH Stdlib::IndexTrait#e80543a5 CARTESIAN PRODUCT OUTPUT Lhs.0, Rhs.0

         18807   ~0%    {2} r3 = JOIN `TypeInference::getCallExprTraitQualifier/1#c084fe9f` WITH TypeInference::MethodResolution::MethodCallCallExpr#6eae461f ON FIRST 1 OUTPUT Lhs.0, Lhs.1

           671   ~0%    {1} r4 = JOIN IndexExpr::Generated::IndexExpr#9975e37a WITH `TypeInference::MethodResolution::MethodCallIndexExpr.isInMutableContext/0#dispred#8c8ad425` ON FIRST 1 OUTPUT Lhs.0
           671   ~1%    {2}    | JOIN WITH Stdlib::IndexMutTrait#4d6c31bd CARTESIAN PRODUCT OUTPUT Lhs.0, Rhs.0

        183781   ~0%    {2} r5 = r1 UNION r2 UNION r3 UNION r4
                        return r5

Before
```
Evaluated relational algebra for predicate TypeInference::MethodResolution::MethodCall.getTrait/0#dispred#fc13ba6e@914858bt with tuple counts:
          153112   ~2%    {2} r1 = SCAN `Operation::Operation.isOverloaded/3#f0e64084` OUTPUT In.0, In.1
          153112   ~2%    {2}    | STREAM DEDUP

           18807   ~0%    {2} r2 = JOIN `TypeInference::getCallExprTraitQualifier/1#c084fe9f` WITH TypeInference::MethodResolution::MethodCallCallExpr#6eae461f ON FIRST 1 OUTPUT Lhs.0, Lhs.1

        65859035   ~3%    {3} r3 = JOIN `_IndexExpr::Generated::IndexExpr#9975e37a_TypeInference::MethodResolution::MethodCallIndexExpr.isInM__#shared` WITH Trait::Generated::Trait#ecf50173 CARTESIAN PRODUCT OUTPUT Rhs.0, _, Lhs.0
        65859035   ~0%    {3}    | REWRITE WITH Out.1 := "core::ops::index::Index"
           11191   ~0%    {2}    | JOIN WITH `Addressable::Addressable.getCanonicalPath/0#dispred#6044348f#bb` ON FIRST 2 OUTPUT Lhs.2, Lhs.0

             671   ~0%    {1} r4 = JOIN IndexExpr::Generated::IndexExpr#9975e37a WITH `TypeInference::MethodResolution::MethodCallIndexExpr.isInMutableContext/0#dispred#8c8ad425` ON FIRST 1 OUTPUT Lhs.0
         3948835   ~2%    {3}    | JOIN WITH Trait::Generated::Trait#ecf50173 CARTESIAN PRODUCT OUTPUT Rhs.0, _, Lhs.0
         3948835   ~2%    {3}    | REWRITE WITH Out.1 := "core::ops::index::IndexMut"
             671   ~1%    {2}    | JOIN WITH `Addressable::Addressable.getCanonicalPath/0#dispred#6044348f#bb` ON FIRST 2 OUTPUT Lhs.2, Lhs.0

          183781   ~0%    {2} r5 = r1 UNION r2 UNION r3 UNION r4
                          return r5
```

After
```
Evaluated relational algebra for predicate TypeInference::MethodResolution::MethodCall.getTrait/0#dispred#fc13ba6e@1b4a55e3 with tuple counts:
        153112   ~2%    {2} r1 = SCAN `Operation::Operation.isOverloaded/3#f0e64084` OUTPUT In.0, In.1
        153112   ~2%    {2}    | STREAM DEDUP

         11191   ~0%    {2} r2 = JOIN `_IndexExpr::Generated::IndexExpr#9975e37a_TypeInference::MethodResolution::MethodCallIndexExpr.isInM__#shared` WITH Stdlib::IndexTrait#e80543a5 CARTESIAN PRODUCT OUTPUT Lhs.0, Rhs.0

         18807   ~0%    {2} r3 = JOIN `TypeInference::getCallExprTraitQualifier/1#c084fe9f` WITH TypeInference::MethodResolution::MethodCallCallExpr#6eae461f ON FIRST 1 OUTPUT Lhs.0, Lhs.1

           671   ~0%    {1} r4 = JOIN IndexExpr::Generated::IndexExpr#9975e37a WITH `TypeInference::MethodResolution::MethodCallIndexExpr.isInMutableContext/0#dispred#8c8ad425` ON FIRST 1 OUTPUT Lhs.0
           671   ~1%    {2}    | JOIN WITH Stdlib::IndexMutTrait#4d6c31bd CARTESIAN PRODUCT OUTPUT Lhs.0, Rhs.0

        183781   ~0%    {2} r5 = r1 UNION r2 UNION r3 UNION r4
                        return r5
```
@github-actions github-actions bot added the Rust Pull requests that update Rust code label Dec 17, 2025
@hvitved hvitved added the no-change-note-required This PR does not need a change note label Dec 17, 2025
@hvitved hvitved marked this pull request as ready for review December 17, 2025 10:59
@hvitved hvitved requested a review from a team as a code owner December 17, 2025 10:59
Copilot AI review requested due to automatic review settings December 17, 2025 10:59
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR optimizes a QL query by refactoring trait lookups for index operations. Instead of using string comparisons with getCanonicalPath(), the code now uses instanceof checks with dedicated trait classes, significantly improving performance by reducing tuple counts in the relational algebra evaluation from ~66 million to ~4 million.

  • Introduces a new IndexMutTrait class in the Stdlib module
  • Refactors MethodCallIndexExpr.getTrait() to use instanceof checks instead of string comparisons

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
rust/ql/lib/codeql/rust/frameworks/stdlib/Stdlib.qll Adds the IndexMutTrait class to represent the core::ops::index::IndexMut trait, following the same pattern as the existing IndexTrait class
rust/ql/lib/codeql/rust/internal/TypeInference.qll Refactors getTrait() method to use instanceof IndexMutTrait and instanceof IndexTrait instead of string comparisons with getCanonicalPath()

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@hvitved hvitved merged commit 47e375f into github:main Dec 17, 2025
27 checks passed
@hvitved hvitved deleted the rust/fix-bad-join branch December 17, 2025 14:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

no-change-note-required This PR does not need a change note Rust Pull requests that update Rust code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants