rust-lang / rust-lang/rfcs

Delegating permissions to implement Trait

Open
#2,946 8 comments 2 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Markdown
Stars
6.6k
Forks
1.7k
Avg merge
16h 14m
Merged PRs (30d)
1

Description

Currently, it is only possible to implement traits on types if either:

a. a crate owns the type
b. a crate owns the trait

The reasoning for that, as far as I understand, is that allowing random crates to implement traits on types where they own neither we quickly end up in a situation where there are competing implementations of traits in which rust can't decide anymore which is the "right one".

This can lead to an unpleasant situation for traits that are generally useful where:

A crate implementing a common, useful, widely used, the trait has to depend on and implement traits on a large number of other crates they wish to implement the trait for - usually accompanied by a number of feature flags so users can cut down the dependency graph.

A crate implementing a common type having to depend on and pull in a number of trait-crates to implement their traits. Again usually accompanied by a number of feature flags to cut down the use of unused dependencies.

An example

The probably best example for such a case is serde, which, rightfully so, a lot of crates depend on because it offers an important trait that crates might implement.

At the time of writing, there are over 5000 crates (https://crates.io/crates/serde-json/reverse_dependencies) depending on it which to a large degree, if you just use them for functionality do not require serde at all.

(note this is not a criticism on serde or any library using its traits!)

Proposal

Allowing crates to delegate the right to implement traits on their types, or implement their trait for types to other crates would allow people to opt in / out of dependencies in an independent manner from feature flags.

In other words, a crate a could specify a list of other crates (b, c, d) that are allowed to either B, C, D are allowed to implement traits in A on types that are neither owned by A nor themselves or implement traits that neither they nor A own on types owned by A.

Since permissions would need to be explicitly delegated by a create that has the permissions themselves this would not break the initial reason of conflicting trait implementations on types.

Cargo.toml (for crate a)

delegate-trait = ["a", "b", "c"] # might need a better name but that's a detail

An example (again):

The user of the url crate could delegate permissions to a crate url-serde so that url-serde could implement Serialize and Deserialize on the types defined in url. This would remove the need for future flags and people wishing to use serialization with url can explicitly add the extra dependency.

limitations

A limitation with this minimalistic approach would be that derive based traits couldn't be delegated. However, nothing in this proposal would block adding this later on with an additional construct around deriving for foreign structs.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reviewing the proposed delegate-trait entry in Cargo.toml and the stated serde/url example. Define the delegation rules, conflict guarantees, and derive-trait limitation in an RFC before implementation; done means the design is resolved and documented well enough to assess its compiler and Cargo impact.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.