Skip to content

Propose polymorphization project goal - #751

Open
camelid wants to merge 2 commits into
rust-lang:mainfrom
camelid:poly
Open

Propose polymorphization project goal#751
camelid wants to merge 2 commits into
rust-lang:mainfrom
camelid:poly

Conversation

@camelid

@camelid camelid commented Aug 5, 2026

Copy link
Copy Markdown
Member

Implement experimental support in the Rust compiler for polymorphic code generation. Instead of monomorphizing generic code, the compiler will generate type-agnostic instances and add hidden vtable parameters where needed, which should reduce compile times and generated binary sizes.

Rendered

@camelid

camelid commented Aug 5, 2026

Copy link
Copy Markdown
Member Author

There is already extensive discussion of this work on Zulip. Also cc my WIP PR containing the proof of concept: rust-lang/rust#160300

@nxsaken nxsaken added the C-goal-proposal This is a goal proposal label Aug 5, 2026
@rustbot

rustbot commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator

A zulip topic was opened to discuss this issue.

@jlizen jlizen left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Great content, some suggestions

View changes since this review


## Motivation

### The status quo

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is well laid out for the build speed case. No binary size benefits though? Are we not focused on release artifacts yet?


I plan to implement support for truly polymorphic code generation in Rustc. Unlike the previous polymorphization project, my design works for unused and used generic parameters alike, significantly expanding its potential benefits and sidestepping issues with determining whether parameters are relevant to codegen. The axiom is "monomorphic data, polymorphic code". In other words, unlike languages like Haskell and OCaml that generally rely on uniform representations (boxing) to enable polymorphic code generation, data layouts will stay the same under polymorphization, and only function ABIs will change. Polymorphized instances can coexist with monomorphized instances, enabling incremental improvements to the kinds of functions supported by polymorphization. In fact, polymorphization operates at the (type) parameter level, so some parameters can be polymorphized (becoming "erased types"), while others remain monomorphized, within a single function.

I estimate that the full version of polymorphization could speed up codegen and linking by between 30% and 2x, by eliminating up to half of generated instances in many cases. Binary sizes should also be reduced as a result, without requiring link-time optimization, helping shrink the size of artifact directories containing debug builds. As mentioned, incremental progress can be made toward this full vision, providing checkpoints with smaller but noticeable speedups and binary size reductions.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I see we mention binary sizes here, i think it is worth mentioning size bloat in the status quo as well


Data layouts are not the only thing generic code needs to know about its type parameters. Trait methods and associated types also come into play, as do drop glue and `TypeId` information. The key is that all of this information already must be known statically at some point in the call graph. Thus, it can be threaded through implicit function arguments inserted during codegen. Essentially, each type parameter will generate a hidden extended-vtable argument containing the type's `TypeId`, its drop glue function pointer, and each of its trait methods' function pointers. Type parameters whose bounded traits have associated types will generate additional vtable arguments, one per associated type.

#### Prior art

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is great context thanks

## Funding


| Purpose | Cost | Funded | Sponsor(s) |

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Interested in learning more about funding needs, but I'll ask as instructed :)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It might be worth including a loose timeline (assuming full funding)? Even just a "total X months" granularity helps, though something like "MCP after X, start of impl lands after Y, full experimental MVP Z" is even nicer.

https://rust-lang.github.io/rust-project-goals/2026/incremental-system-rethought.html#target-timeline is a great example though it's ok if that level of detail is not known and step 0 is just discovery.


I plan to implement support for truly polymorphic code generation in Rustc. Unlike the previous polymorphization project, my design works for unused and used generic parameters alike, significantly expanding its potential benefits and sidestepping issues with determining whether parameters are relevant to codegen. The axiom is "monomorphic data, polymorphic code". In other words, unlike languages like Haskell and OCaml that generally rely on uniform representations (boxing) to enable polymorphic code generation, data layouts will stay the same under polymorphization, and only function ABIs will change. Polymorphized instances can coexist with monomorphized instances, enabling incremental improvements to the kinds of functions supported by polymorphization. In fact, polymorphization operates at the (type) parameter level, so some parameters can be polymorphized (becoming "erased types"), while others remain monomorphized, within a single function.

I estimate that the full version of polymorphization could speed up codegen and linking by between 30% and 2x, by eliminating up to half of generated instances in many cases. Binary sizes should also be reduced as a result, without requiring link-time optimization, helping shrink the size of artifact directories containing debug builds. As mentioned, incremental progress can be made toward this full vision, providing checkpoints with smaller but noticeable speedups and binary size reductions.

@jlizen jlizen Aug 6, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I would hoist this into an "expected outcomes" section, right now it is buried in implementation details

Comment on lines +53 to +54
| Support simple dyn-compatible traits | @camelid | |
| Support some non-dyn-compatible traits | @camelid | |

@jackh726 jackh726 Aug 7, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

These seem like they would need types review, probably at least small.

Separately, the approach of adding a TyKind::Erased will need a types vibecheck.

View changes since the review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

C-goal-proposal This is a goal proposal

Projects

Status: To Do

Development

Successfully merging this pull request may close these issues.

5 participants