Sitelet https://github.com/obi1kenobi/trustfall-rustdoc-adapter/pull/926
Skip to content

Initial work towards dynamically resolving enum variants. - #926

Merged
obi1kenobi merged 3 commits into
obi1kenobi:rustdoc-v55from
CLIDragon:resolve-variants-v54
Aug 9, 2025
Merged

obi1kenobi merged 3 commits into
obi1kenobi:rustdoc-v55from
CLIDragon:resolve-variants-v54

Conversation

@CLIDragon

Copy link
Copy Markdown
Contributor

Purpose of Change
Resolving enum variants costs a lot of time in already heavy queries. In particular, the following lints will run faster after this change.

enum_no_repr_variant_discriminant_changed
enum_unit_variant_changed_kind
enum_variant_marked_non_exhaustive
enum_variant_missing
partial_ord_enum_variants_reordered

Describe the Change
Implement a custom resolver for enum variants based on a new index.

Additional Context
If all of the above lints act only on public enums then index creation can be made faster by using pub_item_kind_index.

Comment thread src/adapter/edges.rs
Comment thread src/adapter/edges.rs Outdated
Comment thread src/indexed_crate.rs Outdated
Comment thread src/indexed_crate.rs Outdated
Comment thread src/indexed_crate.rs Outdated
let base_iter = enum_item.variants.iter();

base_iter.copied().enumerate().map(move |(i, var_id)| {
let var = index.get(&var_id).expect("Variant id should be correct.");

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

rustdoc JSON occasionally has bugs that result in dangling IDs, and some of those issues are still open. We shouldn't hit this panic, but we might.

Slight preference for using filter_map() and omitting invalid items from the index instead of exploding, just so we don't cause ourselves extra support burden if such a bug affects our users.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I have made the change, but I'm not convinced that it's a good idea. If dangling ids do exist, then it's likely that they will cause a false positive in enum_variant_missing. Then, instead of being able to point to the backtrace and easily identify the cause as dangling ids in rustdoc, there will be no clear signal that determines the cause.

Comment thread src/indexed_crate.rs Outdated
@obi1kenobi

Copy link
Copy Markdown
Owner

Broadly looks in decent shape, just needs some more polishing to improve maintainability: using unreachable!() with a good comment that includes the problematic values instead of a bare panic!(), using .expect() (or even .unwrap_or_else(|| unreachable!("format string: {data:?}"))) instead of .unwrap(), etc.

@CLIDragon
CLIDragon requested a review from obi1kenobi July 28, 2025 11:36
@CLIDragon

Copy link
Copy Markdown
Contributor Author

This is ready for review. I'm not happy with the code duplication in build_variant_name_index but I can't see a way around it.

@CLIDragon

CLIDragon commented Aug 2, 2025 •

Copy link
Copy Markdown
Contributor Author

After some more analysis, this isn't producing the performance results that I had initially hoped for. I would like to see whether there are other ways of speeding up the same queries that are more impactful.

EDIT: After a little more research, the only really discontinuous query is enum_unit_variant_changed_kind.

obi1kenobi added a commit that referenced this pull request Aug 4, 2025
…h. (#927)

**Purpose of Change**
This is something that is done a lot and is basically copy-pasted
between call sites. Especially in lookup code, such as in #926, the
match can harm readability.

**Describe the Change**
Introduce a new function `crate_at_origin`. Since it's `pub(crate)`, it
won't affect the API, but it can make internal code easier to read. I
have changed some of the uses to demonstrate the changes.

**Describe Alternatives**
Perhaps `package_index_at_origin` may be a better name.

---------

Co-authored-by: Predrag Gruevski <2348618+obi1kenobi@users.noreply.github.com>
obi1kenobi added a commit that referenced this pull request Aug 4, 2025
…h. (#927)

**Purpose of Change**
This is something that is done a lot and is basically copy-pasted
between call sites. Especially in lookup code, such as in #926, the
match can harm readability.

**Describe the Change**
Introduce a new function `crate_at_origin`. Since it's `pub(crate)`, it
won't affect the API, but it can make internal code easier to read. I
have changed some of the uses to demonstrate the changes.

**Describe Alternatives**
Perhaps `package_index_at_origin` may be a better name.

---------

Co-authored-by: Predrag Gruevski <2348618+obi1kenobi@users.noreply.github.com>
obi1kenobi added a commit that referenced this pull request Aug 4, 2025
…h. (#927)

**Purpose of Change**
This is something that is done a lot and is basically copy-pasted
between call sites. Especially in lookup code, such as in #926, the
match can harm readability.

**Describe the Change**
Introduce a new function `crate_at_origin`. Since it's `pub(crate)`, it
won't affect the API, but it can make internal code easier to read. I
have changed some of the uses to demonstrate the changes.

**Describe Alternatives**
Perhaps `package_index_at_origin` may be a better name.

---------

Co-authored-by: Predrag Gruevski <2348618+obi1kenobi@users.noreply.github.com>
obi1kenobi added a commit that referenced this pull request Aug 4, 2025
…h. (#927)

**Purpose of Change**
This is something that is done a lot and is basically copy-pasted
between call sites. Especially in lookup code, such as in #926, the
match can harm readability.

**Describe the Change**
Introduce a new function `crate_at_origin`. Since it's `pub(crate)`, it
won't affect the API, but it can make internal code easier to read. I
have changed some of the uses to demonstrate the changes.

**Describe Alternatives**
Perhaps `package_index_at_origin` may be a better name.

---------

Co-authored-by: Predrag Gruevski <2348618+obi1kenobi@users.noreply.github.com>
obi1kenobi added a commit that referenced this pull request Aug 4, 2025
…h. (#927)

**Purpose of Change**
This is something that is done a lot and is basically copy-pasted
between call sites. Especially in lookup code, such as in #926, the
match can harm readability.

**Describe the Change**
Introduce a new function `crate_at_origin`. Since it's `pub(crate)`, it
won't affect the API, but it can make internal code easier to read. I
have changed some of the uses to demonstrate the changes.

**Describe Alternatives**
Perhaps `package_index_at_origin` may be a better name.

---------

Co-authored-by: Predrag Gruevski <2348618+obi1kenobi@users.noreply.github.com>
obi1kenobi added a commit that referenced this pull request Aug 4, 2025
…h. (#927) (#929)

**Purpose of Change**
This is something that is done a lot and is basically copy-pasted
between call sites. Especially in lookup code, such as in #926, the
match can harm readability.

**Describe the Change**
Introduce a new function `crate_at_origin`. Since it's `pub(crate)`, it
won't affect the API, but it can make internal code easier to read. I
have changed some of the uses to demonstrate the changes.

**Describe Alternatives**
Perhaps `package_index_at_origin` may be a better name.

---------

Co-authored-by: Predrag Gruevski
<2348618+obi1kenobi@users.noreply.github.com>

Co-authored-by: CLIDragon <84266961+CLIDragon@users.noreply.github.com>
obi1kenobi added a commit that referenced this pull request Aug 4, 2025
…h. (#927) (#930)

**Purpose of Change**
This is something that is done a lot and is basically copy-pasted
between call sites. Especially in lookup code, such as in #926, the
match can harm readability.

**Describe the Change**
Introduce a new function `crate_at_origin`. Since it's `pub(crate)`, it
won't affect the API, but it can make internal code easier to read. I
have changed some of the uses to demonstrate the changes.

**Describe Alternatives**
Perhaps `package_index_at_origin` may be a better name.

---------

Co-authored-by: Predrag Gruevski
<2348618+obi1kenobi@users.noreply.github.com>

Co-authored-by: CLIDragon <84266961+CLIDragon@users.noreply.github.com>
obi1kenobi added a commit that referenced this pull request Aug 4, 2025
…h. (#927) (#931)

**Purpose of Change**
This is something that is done a lot and is basically copy-pasted
between call sites. Especially in lookup code, such as in #926, the
match can harm readability.

**Describe the Change**
Introduce a new function `crate_at_origin`. Since it's `pub(crate)`, it
won't affect the API, but it can make internal code easier to read. I
have changed some of the uses to demonstrate the changes.

**Describe Alternatives**
Perhaps `package_index_at_origin` may be a better name.

---------

Co-authored-by: Predrag Gruevski
<2348618+obi1kenobi@users.noreply.github.com>

Co-authored-by: CLIDragon <84266961+CLIDragon@users.noreply.github.com>
@CLIDragon
CLIDragon marked this pull request as ready for review August 7, 2025 09:14
@CLIDragon

Copy link
Copy Markdown
Contributor Author

After some review, resolving variants does appear to have the intended effect - it's simply smaller in magnitude than I was hoping for.

@CLIDragon
CLIDragon force-pushed the resolve-variants-v54 branch from 6cc49e9 to 9888ade Compare August 7, 2025 09:33
@CLIDragon
CLIDragon changed the base branch from rustdoc-v54 to rustdoc-v55 August 7, 2025 09:33
@CLIDragon
CLIDragon marked this pull request as draft August 7, 2025 09:52
@CLIDragon
CLIDragon marked this pull request as ready for review August 7, 2025 09:56
@CLIDragon
CLIDragon marked this pull request as draft August 8, 2025 12:21
@CLIDragon

Copy link
Copy Markdown
Contributor Author

Apologies for the churn. While the variant resolution itself appears to be correct, I'm currently running into an issue where tracing reports that this should be reducing enum_unit_variant_changed_kind runtime by nearly 90%, when in practice it only reduces it by ~10%.

@obi1kenobi

Copy link
Copy Markdown
Owner

No worries at all. If you feel a second pair of eyes on the trace might be helpful, I'm happy to take a look too!

@CLIDragon

Copy link
Copy Markdown
Contributor Author

Running c-s-c again, I find that this does produce the correct speedup, so I'm guessing that I mixed up different experiments when I initially recorded the changes.

@obi1kenobi Could you confirm that, when running on 4 threads in release mode on aws_sdk_ec2, enum_unit_variant_changed_kind initially takes around 0.38 seconds and after including this patch, takes around 0.02 seconds?

@obi1kenobi

Copy link
Copy Markdown
Owner

Yes, I'm seeing a 10x speedup on that lint with this branch patched in than without it.

unpatched:
        PASS [   0.885s]       major        enum_unit_variant_changed_kind
        PASS [   0.858s]       major        enum_unit_variant_changed_kind        
        PASS [   0.848s]       major        enum_unit_variant_changed_kind

patched w/ this branch:
        PASS [   0.082s]       major        enum_unit_variant_changed_kind
        PASS [   0.074s]       major        enum_unit_variant_changed_kind
        PASS [   0.083s]       major        enum_unit_variant_changed_kind

@CLIDragon
CLIDragon marked this pull request as ready for review August 9, 2025 03:02
@CLIDragon

Copy link
Copy Markdown
Contributor Author

Awesome, this should (finally) be ready to merge then.

Comment thread src/adapter/optimizations/variant_lookup.rs Outdated
Comment thread src/adapter/optimizations/variant_lookup.rs
@obi1kenobi

obi1kenobi commented Aug 9, 2025 •

Copy link
Copy Markdown
Owner

Aside from the pub(crate) functions, my remaining concern is that right now I don't think we have any test cases that exercise the statically-known path (@filter with a $variable), and IIRC we don't even have any code that exercises the dynamically-known path (@filter with a %tag) either.

So while I believe the implementation is correct, it's concerning that it might not be (or might break in the future) and we'd never know. Please consider adding test cases that hit both code paths, and produce a non-empty set of results.

To make the @filter with a %tag case, you could match a variant to itself in an optimized fashion like so:

{
    Crate {
        item {
            ... on Enum {
                variant {
                    name @tag @output
                }
                variant {
                    other: name @filter(op: "=", value: ["%name"]) @output
                }
            }
        }
    }
}

This is a bit of a silly query, but it should still be optimized and not be O(n^2).

You could add a new test crate for the optimizations specifically, or extend one of the existing test crates that deals with enum variants — your call.

@obi1kenobi

Copy link
Copy Markdown
Owner

Heads up: since Rust 1.89 was released ~yesterday, I'm hoping to release a new cargo-semver-checks very soon, ideally this weekend time permitting.

It's not a big deal if we can't get this PR in in time, and I don't want you to re-plan your entire weekend over it. There will be more releases! I just wanted to mention it so you aren't surprised.

@CLIDragon
CLIDragon force-pushed the resolve-variants-v54 branch from 9888ade to 97d7ee2 Compare August 9, 2025 05:53
Comparing enum variants by name is time consuming because each variant
needs to be compared name by name to find the correct variant. Adding
in a cache reduces this from a quadratic search into an O(1) lookup.
@CLIDragon
CLIDragon force-pushed the resolve-variants-v54 branch from 97d7ee2 to fe13742 Compare August 9, 2025 05:55
@CLIDragon

Copy link
Copy Markdown
Contributor Author

I've added tests and removed the excess pub(crate)s.

@obi1kenobi obi1kenobi left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Awesome work!

Comment thread src/adapter/optimizations/variant_lookup.rs Outdated
Comment thread src/indexed_crate.rs Outdated
@obi1kenobi
obi1kenobi enabled auto-merge (squash) August 9, 2025 14:18
@obi1kenobi
obi1kenobi merged commit ee5daeb into obi1kenobi:rustdoc-v55 Aug 9, 2025
obi1kenobi added a commit that referenced this pull request Aug 9, 2025
**Purpose of Change**
Resolving enum variants costs a lot of time in already heavy queries. In
particular, the following lints will run faster after this change.
```
enum_no_repr_variant_discriminant_changed
enum_unit_variant_changed_kind
enum_variant_marked_non_exhaustive
enum_variant_missing
partial_ord_enum_variants_reordered
```

**Describe the Change**
Implement a custom resolver for enum variants based on a new index.

**Additional Context**
If all of the above lints act only on public enums then index creation
can be made faster by using `pub_item_kind_index`.

---------

Co-authored-by: Predrag Gruevski <2348618+obi1kenobi@users.noreply.github.com>
obi1kenobi added a commit that referenced this pull request Aug 9, 2025
**Purpose of Change**
Resolving enum variants costs a lot of time in already heavy queries. In
particular, the following lints will run faster after this change.
```
enum_no_repr_variant_discriminant_changed
enum_unit_variant_changed_kind
enum_variant_marked_non_exhaustive
enum_variant_missing
partial_ord_enum_variants_reordered
```

**Describe the Change**
Implement a custom resolver for enum variants based on a new index.

**Additional Context**
If all of the above lints act only on public enums then index creation
can be made faster by using `pub_item_kind_index`.

---------

Co-authored-by: Predrag Gruevski
<2348618+obi1kenobi@users.noreply.github.com>

Co-authored-by: CLIDragon <84266961+CLIDragon@users.noreply.github.com>
obi1kenobi added a commit that referenced this pull request Aug 9, 2025
**Purpose of Change**
Resolving enum variants costs a lot of time in already heavy queries. In
particular, the following lints will run faster after this change.
```
enum_no_repr_variant_discriminant_changed
enum_unit_variant_changed_kind
enum_variant_marked_non_exhaustive
enum_variant_missing
partial_ord_enum_variants_reordered
```

**Describe the Change**
Implement a custom resolver for enum variants based on a new index.

**Additional Context**
If all of the above lints act only on public enums then index creation
can be made faster by using `pub_item_kind_index`.

---------

Co-authored-by: Predrag Gruevski
<2348618+obi1kenobi@users.noreply.github.com>

Co-authored-by: CLIDragon <84266961+CLIDragon@users.noreply.github.com>
obi1kenobi added a commit that referenced this pull request Aug 9, 2025
**Purpose of Change**
Resolving enum variants costs a lot of time in already heavy queries. In
particular, the following lints will run faster after this change.
```
enum_no_repr_variant_discriminant_changed
enum_unit_variant_changed_kind
enum_variant_marked_non_exhaustive
enum_variant_missing
partial_ord_enum_variants_reordered
```

**Describe the Change**
Implement a custom resolver for enum variants based on a new index.

**Additional Context**
If all of the above lints act only on public enums then index creation
can be made faster by using `pub_item_kind_index`.

---------

Co-authored-by: Predrag Gruevski
<2348618+obi1kenobi@users.noreply.github.com>

Co-authored-by: CLIDragon <84266961+CLIDragon@users.noreply.github.com>
obi1kenobi added a commit that referenced this pull request Aug 9, 2025
… (#937)

**Purpose of Change**
Resolving enum variants costs a lot of time in already heavy queries. In
particular, the following lints will run faster after this change.
```
enum_no_repr_variant_discriminant_changed
enum_unit_variant_changed_kind
enum_variant_marked_non_exhaustive
enum_variant_missing
partial_ord_enum_variants_reordered
```

**Describe the Change**
Implement a custom resolver for enum variants based on a new index.

**Additional Context**
If all of the above lints act only on public enums then index creation
can be made faster by using `pub_item_kind_index`.

---------

Co-authored-by: Predrag Gruevski
<2348618+obi1kenobi@users.noreply.github.com>

Co-authored-by: CLIDragon <84266961+CLIDragon@users.noreply.github.com>

Co-authored-by: CLIDragon <84266961+CLIDragon@users.noreply.github.com>
obi1kenobi added a commit that referenced this pull request Aug 9, 2025
… (#938)

**Purpose of Change**
Resolving enum variants costs a lot of time in already heavy queries. In
particular, the following lints will run faster after this change.
```
enum_no_repr_variant_discriminant_changed
enum_unit_variant_changed_kind
enum_variant_marked_non_exhaustive
enum_variant_missing
partial_ord_enum_variants_reordered
```

**Describe the Change**
Implement a custom resolver for enum variants based on a new index.

**Additional Context**
If all of the above lints act only on public enums then index creation
can be made faster by using `pub_item_kind_index`.

---------

Co-authored-by: Predrag Gruevski
<2348618+obi1kenobi@users.noreply.github.com>

Co-authored-by: CLIDragon <84266961+CLIDragon@users.noreply.github.com>

Co-authored-by: CLIDragon <84266961+CLIDragon@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants