Skip to content

Rust: Fix two bad joins#21495

Open
hvitved wants to merge 1 commit intogithub:mainfrom
hvitved:rust/fix-bad-joins
Open

Rust: Fix two bad joins#21495
hvitved wants to merge 1 commit intogithub:mainfrom
hvitved:rust/fix-bad-joins

Conversation

@hvitved
Copy link
Contributor

@hvitved hvitved commented Mar 18, 2026

#21488 follow-up.

Before

Evaluated relational algebra for predicate TypeInference::DeconstructionPatMatchingInput::Access.getNodeAt/1#dispred#cc149bc2@88f6f09n with tuple counts:
           142521   ~1%    {3} r1 = JOIN num#FunctionType::TReturnFunctionPosition#a15fd6be WITH TypeInference::DeconstructionPatMatchingInput::Access#a2676dcb CARTESIAN PRODUCT OUTPUT Rhs.0, Lhs.0, Rhs.0

           131938   ~0%    {3} r2 = JOIN `TupleStructPat::Generated::TupleStructPat.getField/1#dispred#ac9c1af6` WITH TypeInference::DeconstructionPatMatchingInput::Access#a2676dcb ON FIRST 1 OUTPUT Lhs.1, Lhs.0, Lhs.2
           131938   ~6%    {3}    | JOIN WITH `FunctionType::FunctionPosition.asPosition/0#dispred#efcc0611_10#join_rhs` ON FIRST 1 OUTPUT Lhs.1, Rhs.1, Lhs.2

          3071346   ~0%    {2} r3 = SCAN `Name::Generated::Name.getText/0#dispred#107a5a39` OUTPUT In.1, In.0
        103064442   ~2%    {3}    | JOIN WITH `StructPat::StructPat.getPatField/1#5e21ea0e_102#join_rhs` ON FIRST 1 OUTPUT Rhs.1, Lhs.1, Rhs.2
        103064442   ~3%    {3}    | JOIN WITH TypeInference::DeconstructionPatMatchingInput::Access#a2676dcb ON FIRST 1 OUTPUT Lhs.2, Lhs.1, Lhs.0
        103064438   ~1%    {3}    | JOIN WITH `StructPatField::Generated::StructPatField.getPat/0#dispred#1aadfeff` ON FIRST 1 OUTPUT Lhs.1, Lhs.2, Rhs.1
         20514858   ~2%    {3}    | JOIN WITH `StructField::Generated::StructField.getName/0#dispred#e0248569_10#join_rhs` ON FIRST 1 OUTPUT Lhs.1, Rhs.1, Lhs.2
            59554   ~1%    {3}    | JOIN WITH `StructPat::StructPat.getNthStructField/1#dispred#de537654_021#join_rhs` ON FIRST 2 OUTPUT Rhs.2, Lhs.0, Lhs.2
            59542   ~0%    {3}    | JOIN WITH `FunctionType::FunctionPosition.asPosition/0#dispred#efcc0611_10#join_rhs` ON FIRST 1 OUTPUT Lhs.1, Rhs.1, Lhs.2

           334001   ~0%    {3} r4 = r1 UNION r2 UNION r3
                           return r4

Evaluated relational algebra for predicate TypeInference::ConstructionMatchingInput::Access.getNodeAt/1#dispred#acd835e6@bfb1f1e1 with tuple counts:
          1395153   ~3%    {3} r1 = JOIN TypeInference::ConstructionMatchingInput::PathExprAccess#b7a80c43 WITH num#FunctionType::TReturnFunctionPosition#a15fd6be CARTESIAN PRODUCT OUTPUT Lhs.0, Rhs.0, Lhs.0

            34290   ~3%    {3} r2 = JOIN StructExpr::Generated::StructExpr#d0a89c56 WITH num#FunctionType::TReturnFunctionPosition#a15fd6be CARTESIAN PRODUCT OUTPUT Lhs.0, Rhs.0, Lhs.0

          3071346   ~0%    {2} r3 = SCAN `Name::Generated::Name.getText/0#dispred#107a5a39` OUTPUT In.1, In.0
        145365745   ~0%    {3}    | JOIN WITH `StructExpr::StructExpr.getFieldExpr/1#cd55566d_102#join_rhs` ON FIRST 1 OUTPUT Rhs.1, Lhs.1, Rhs.2
        145365745   ~1%    {3}    | JOIN WITH StructExpr::Generated::StructExpr#d0a89c56 ON FIRST 1 OUTPUT Lhs.1, Lhs.0, Lhs.2
         33371514   ~0%    {3}    | JOIN WITH `StructField::Generated::StructField.getName/0#dispred#e0248569_10#join_rhs` ON FIRST 1 OUTPUT Lhs.1, Rhs.1, Lhs.2
           108831   ~0%    {3}    | JOIN WITH `StructExpr::StructExpr.getNthStructField/1#dispred#89ad7e20_021#join_rhs` ON FIRST 2 OUTPUT Rhs.2, Lhs.0, Lhs.2
           108751   ~0%    {3}    | JOIN WITH `FunctionType::FunctionPosition.asPosition/0#dispred#efcc0611_10#join_rhs` ON FIRST 1 OUTPUT Lhs.2, Lhs.1, Rhs.1
           108751   ~4%    {3}    | JOIN WITH `StructExprField::Generated::StructExprField.getExpr/0#dispred#956e6ba1` ON FIRST 1 OUTPUT Lhs.1, Lhs.2, Rhs.1

          1748398   ~4%    {3} r4 = `TypeInference::ConstructionMatchingInput::NonAssocCallAccess.getNodeAt/1#dispred#ef232b1f` UNION r1 UNION r2 UNION r3
                           return r4

After

Evaluated relational algebra for predicate TypeInference::DeconstructionPatMatchingInput::Access.getNodeAt/1#dispred#cc149bc2@2ea6ebjs with tuple counts:
        142521   ~1%    {3} r1 = JOIN num#FunctionType::TReturnFunctionPosition#a15fd6be WITH TypeInference::DeconstructionPatMatchingInput::Access#a2676dcb CARTESIAN PRODUCT OUTPUT Rhs.0, Lhs.0, Rhs.0

        131938   ~0%    {3} r2 = JOIN `TupleStructPat::Generated::TupleStructPat.getField/1#dispred#ac9c1af6` WITH TypeInference::DeconstructionPatMatchingInput::Access#a2676dcb ON FIRST 1 OUTPUT Lhs.1, Lhs.0, Lhs.2
        131938   ~6%    {3}    | JOIN WITH `FunctionType::FunctionPosition.asPosition/0#dispred#efcc0611_10#join_rhs` ON FIRST 1 OUTPUT Lhs.1, Rhs.1, Lhs.2

        166829   ~3%    {3} r3 = JOIN `_Name::Generated::Name.getText/0#dispred#107a5a39_StructField::Generated::StructField.getName/0#disp__#shared` WITH `StructPat::StructPat.getNthStructField/1#dispred#de537654_201#join_rhs` ON FIRST 1 OUTPUT Rhs.1, Lhs.1, Rhs.2
        166817   ~2%    {3}    | JOIN WITH TypeInference::DeconstructionPatMatchingInput::Access#a2676dcb ON FIRST 1 OUTPUT Lhs.2, Lhs.1, Lhs.0
        166817   ~0%    {3}    | JOIN WITH `FunctionType::FunctionPosition.asPosition/0#dispred#efcc0611_10#join_rhs` ON FIRST 1 OUTPUT Lhs.2, Lhs.1, Rhs.1
         59542   ~0%    {3}    | JOIN WITH `StructPat::StructPat.getPatField/1#5e21ea0e` ON FIRST 2 OUTPUT Rhs.2, Lhs.0, Lhs.2
         59542   ~0%    {3}    | JOIN WITH `StructPatField::Generated::StructPatField.getPat/0#dispred#1aadfeff` ON FIRST 1 OUTPUT Lhs.1, Lhs.2, Rhs.1

        334001   ~0%    {3} r4 = r1 UNION r2 UNION r3
                        return r4

Evaluated relational algebra for predicate TypeInference::ConstructionMatchingInput::Access.getNodeAt/1#dispred#acd835e6@c7f267fp with tuple counts:
        1395153   ~3%    {3} r1 = JOIN TypeInference::ConstructionMatchingInput::PathExprAccess#b7a80c43 WITH num#FunctionType::TReturnFunctionPosition#a15fd6be CARTESIAN PRODUCT OUTPUT Lhs.0, Rhs.0, Lhs.0

          34290   ~3%    {3} r2 = JOIN StructExpr::Generated::StructExpr#d0a89c56 WITH num#FunctionType::TReturnFunctionPosition#a15fd6be CARTESIAN PRODUCT OUTPUT Lhs.0, Rhs.0, Lhs.0

         159331   ~0%    {3} r3 = JOIN `_Name::Generated::Name.getText/0#dispred#107a5a39_StructField::Generated::StructField.getName/0#disp__#shared` WITH `StructExpr::StructExpr.getNthStructField/1#dispred#89ad7e20_201#join_rhs` ON FIRST 1 OUTPUT Rhs.1, Lhs.1, Rhs.2
         159231   ~3%    {3}    | JOIN WITH StructExpr::Generated::StructExpr#d0a89c56 ON FIRST 1 OUTPUT Lhs.2, Lhs.1, Lhs.0
         159231   ~3%    {3}    | JOIN WITH `FunctionType::FunctionPosition.asPosition/0#dispred#efcc0611_10#join_rhs` ON FIRST 1 OUTPUT Lhs.2, Lhs.1, Rhs.1
         108731   ~0%    {3}    | JOIN WITH `StructExpr::StructExpr.getFieldExpr/1#cd55566d` ON FIRST 2 OUTPUT Rhs.2, Lhs.0, Lhs.2
         108731   ~4%    {3}    | JOIN WITH `StructExprField::Generated::StructExprField.getExpr/0#dispred#956e6ba1` ON FIRST 1 OUTPUT Lhs.1, Lhs.2, Rhs.1

        1748378   ~4%    {3} r4 = `TypeInference::ConstructionMatchingInput::NonAssocCallAccess.getNodeAt/1#dispred#ef232b1f` UNION r1 UNION r2 UNION r3
                         return r4

Before
```
Evaluated relational algebra for predicate TypeInference::DeconstructionPatMatchingInput::Access.getNodeAt/1#dispred#cc149bc2@88f6f09n with tuple counts:
           142521   ~1%    {3} r1 = JOIN num#FunctionType::TReturnFunctionPosition#a15fd6be WITH TypeInference::DeconstructionPatMatchingInput::Access#a2676dcb CARTESIAN PRODUCT OUTPUT Rhs.0, Lhs.0, Rhs.0

           131938   ~0%    {3} r2 = JOIN `TupleStructPat::Generated::TupleStructPat.getField/1#dispred#ac9c1af6` WITH TypeInference::DeconstructionPatMatchingInput::Access#a2676dcb ON FIRST 1 OUTPUT Lhs.1, Lhs.0, Lhs.2
           131938   ~6%    {3}    | JOIN WITH `FunctionType::FunctionPosition.asPosition/0#dispred#efcc0611_10#join_rhs` ON FIRST 1 OUTPUT Lhs.1, Rhs.1, Lhs.2

          3071346   ~0%    {2} r3 = SCAN `Name::Generated::Name.getText/0#dispred#107a5a39` OUTPUT In.1, In.0
        103064442   ~2%    {3}    | JOIN WITH `StructPat::StructPat.getPatField/1#5e21ea0e_102#join_rhs` ON FIRST 1 OUTPUT Rhs.1, Lhs.1, Rhs.2
        103064442   ~3%    {3}    | JOIN WITH TypeInference::DeconstructionPatMatchingInput::Access#a2676dcb ON FIRST 1 OUTPUT Lhs.2, Lhs.1, Lhs.0
        103064438   ~1%    {3}    | JOIN WITH `StructPatField::Generated::StructPatField.getPat/0#dispred#1aadfeff` ON FIRST 1 OUTPUT Lhs.1, Lhs.2, Rhs.1
         20514858   ~2%    {3}    | JOIN WITH `StructField::Generated::StructField.getName/0#dispred#e0248569_10#join_rhs` ON FIRST 1 OUTPUT Lhs.1, Rhs.1, Lhs.2
            59554   ~1%    {3}    | JOIN WITH `StructPat::StructPat.getNthStructField/1#dispred#de537654_021#join_rhs` ON FIRST 2 OUTPUT Rhs.2, Lhs.0, Lhs.2
            59542   ~0%    {3}    | JOIN WITH `FunctionType::FunctionPosition.asPosition/0#dispred#efcc0611_10#join_rhs` ON FIRST 1 OUTPUT Lhs.1, Rhs.1, Lhs.2

           334001   ~0%    {3} r4 = r1 UNION r2 UNION r3
                           return r4

Evaluated relational algebra for predicate TypeInference::ConstructionMatchingInput::Access.getNodeAt/1#dispred#acd835e6@bfb1f1e1 with tuple counts:
          1395153   ~3%    {3} r1 = JOIN TypeInference::ConstructionMatchingInput::PathExprAccess#b7a80c43 WITH num#FunctionType::TReturnFunctionPosition#a15fd6be CARTESIAN PRODUCT OUTPUT Lhs.0, Rhs.0, Lhs.0

            34290   ~3%    {3} r2 = JOIN StructExpr::Generated::StructExpr#d0a89c56 WITH num#FunctionType::TReturnFunctionPosition#a15fd6be CARTESIAN PRODUCT OUTPUT Lhs.0, Rhs.0, Lhs.0

          3071346   ~0%    {2} r3 = SCAN `Name::Generated::Name.getText/0#dispred#107a5a39` OUTPUT In.1, In.0
        145365745   ~0%    {3}    | JOIN WITH `StructExpr::StructExpr.getFieldExpr/1#cd55566d_102#join_rhs` ON FIRST 1 OUTPUT Rhs.1, Lhs.1, Rhs.2
        145365745   ~1%    {3}    | JOIN WITH StructExpr::Generated::StructExpr#d0a89c56 ON FIRST 1 OUTPUT Lhs.1, Lhs.0, Lhs.2
         33371514   ~0%    {3}    | JOIN WITH `StructField::Generated::StructField.getName/0#dispred#e0248569_10#join_rhs` ON FIRST 1 OUTPUT Lhs.1, Rhs.1, Lhs.2
           108831   ~0%    {3}    | JOIN WITH `StructExpr::StructExpr.getNthStructField/1#dispred#89ad7e20_021#join_rhs` ON FIRST 2 OUTPUT Rhs.2, Lhs.0, Lhs.2
           108751   ~0%    {3}    | JOIN WITH `FunctionType::FunctionPosition.asPosition/0#dispred#efcc0611_10#join_rhs` ON FIRST 1 OUTPUT Lhs.2, Lhs.1, Rhs.1
           108751   ~4%    {3}    | JOIN WITH `StructExprField::Generated::StructExprField.getExpr/0#dispred#956e6ba1` ON FIRST 1 OUTPUT Lhs.1, Lhs.2, Rhs.1

          1748398   ~4%    {3} r4 = `TypeInference::ConstructionMatchingInput::NonAssocCallAccess.getNodeAt/1#dispred#ef232b1f` UNION r1 UNION r2 UNION r3
                           return r4
```

After
```
Evaluated relational algebra for predicate TypeInference::DeconstructionPatMatchingInput::Access.getNodeAt/1#dispred#cc149bc2@2ea6ebjs with tuple counts:
        142521   ~1%    {3} r1 = JOIN num#FunctionType::TReturnFunctionPosition#a15fd6be WITH TypeInference::DeconstructionPatMatchingInput::Access#a2676dcb CARTESIAN PRODUCT OUTPUT Rhs.0, Lhs.0, Rhs.0

        131938   ~0%    {3} r2 = JOIN `TupleStructPat::Generated::TupleStructPat.getField/1#dispred#ac9c1af6` WITH TypeInference::DeconstructionPatMatchingInput::Access#a2676dcb ON FIRST 1 OUTPUT Lhs.1, Lhs.0, Lhs.2
        131938   ~6%    {3}    | JOIN WITH `FunctionType::FunctionPosition.asPosition/0#dispred#efcc0611_10#join_rhs` ON FIRST 1 OUTPUT Lhs.1, Rhs.1, Lhs.2

        166829   ~3%    {3} r3 = JOIN `_Name::Generated::Name.getText/0#dispred#107a5a39_StructField::Generated::StructField.getName/0#disp__#shared` WITH `StructPat::StructPat.getNthStructField/1#dispred#de537654_201#join_rhs` ON FIRST 1 OUTPUT Rhs.1, Lhs.1, Rhs.2
        166817   ~2%    {3}    | JOIN WITH TypeInference::DeconstructionPatMatchingInput::Access#a2676dcb ON FIRST 1 OUTPUT Lhs.2, Lhs.1, Lhs.0
        166817   ~0%    {3}    | JOIN WITH `FunctionType::FunctionPosition.asPosition/0#dispred#efcc0611_10#join_rhs` ON FIRST 1 OUTPUT Lhs.2, Lhs.1, Rhs.1
         59542   ~0%    {3}    | JOIN WITH `StructPat::StructPat.getPatField/1#5e21ea0e` ON FIRST 2 OUTPUT Rhs.2, Lhs.0, Lhs.2
         59542   ~0%    {3}    | JOIN WITH `StructPatField::Generated::StructPatField.getPat/0#dispred#1aadfeff` ON FIRST 1 OUTPUT Lhs.1, Lhs.2, Rhs.1

        334001   ~0%    {3} r4 = r1 UNION r2 UNION r3
                        return r4

Evaluated relational algebra for predicate TypeInference::ConstructionMatchingInput::Access.getNodeAt/1#dispred#acd835e6@c7f267fp with tuple counts:
        1395153   ~3%    {3} r1 = JOIN TypeInference::ConstructionMatchingInput::PathExprAccess#b7a80c43 WITH num#FunctionType::TReturnFunctionPosition#a15fd6be CARTESIAN PRODUCT OUTPUT Lhs.0, Rhs.0, Lhs.0

          34290   ~3%    {3} r2 = JOIN StructExpr::Generated::StructExpr#d0a89c56 WITH num#FunctionType::TReturnFunctionPosition#a15fd6be CARTESIAN PRODUCT OUTPUT Lhs.0, Rhs.0, Lhs.0

         159331   ~0%    {3} r3 = JOIN `_Name::Generated::Name.getText/0#dispred#107a5a39_StructField::Generated::StructField.getName/0#disp__#shared` WITH `StructExpr::StructExpr.getNthStructField/1#dispred#89ad7e20_201#join_rhs` ON FIRST 1 OUTPUT Rhs.1, Lhs.1, Rhs.2
         159231   ~3%    {3}    | JOIN WITH StructExpr::Generated::StructExpr#d0a89c56 ON FIRST 1 OUTPUT Lhs.2, Lhs.1, Lhs.0
         159231   ~3%    {3}    | JOIN WITH `FunctionType::FunctionPosition.asPosition/0#dispred#efcc0611_10#join_rhs` ON FIRST 1 OUTPUT Lhs.2, Lhs.1, Rhs.1
         108731   ~0%    {3}    | JOIN WITH `StructExpr::StructExpr.getFieldExpr/1#cd55566d` ON FIRST 2 OUTPUT Rhs.2, Lhs.0, Lhs.2
         108731   ~4%    {3}    | JOIN WITH `StructExprField::Generated::StructExprField.getExpr/0#dispred#956e6ba1` ON FIRST 1 OUTPUT Lhs.1, Lhs.2, Rhs.1

        1748378   ~4%    {3} r4 = `TypeInference::ConstructionMatchingInput::NonAssocCallAccess.getNodeAt/1#dispred#ef232b1f` UNION r1 UNION r2 UNION r3
                         return r4
```
@github-actions github-actions bot added the Rust Pull requests that update Rust code label Mar 18, 2026
@hvitved hvitved added the no-change-note-required This PR does not need a change note label Mar 19, 2026
@hvitved hvitved marked this pull request as ready for review March 19, 2026 07:42
@hvitved hvitved requested a review from a team as a code owner March 19, 2026 07:42
@hvitved hvitved requested review from Copilot and paldepind March 19, 2026 07:42
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 is a follow-up to #21488 that improves the performance of Rust type inference by fixing two inefficient joins in getNodeAt, using pragma[only_bind_into] to steer join ordering and avoid large intermediate relations.

Changes:

  • Wrap struct field-name lookup keys in pragma[only_bind_into](...) in construction matching (StructExprAccess.getNodeAt).
  • Wrap struct field-name lookup keys in pragma[only_bind_into](...) in deconstruction pattern matching (DeconstructionPatMatchingInput::Access.getNodeAt).

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