Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Automatically implement some traits for ! #1637

Closed
wants to merge 4 commits into from
Closed
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 20 additions & 25 deletions text/0000-bang-auto-impls.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@
[summary]: #summary

Make `!` automatically implement traits for which it has only a single possible
implementation. Add a `#[dont_impl_for_bang]` trait attribute to opt-out of
this behaviour.
implementation.

# Motivation
[motivation]: #motivation
Expand Down Expand Up @@ -77,48 +76,44 @@ implementation automatically derived. This includes all traits *except*:
* Traits which have an associated type:
Because there are many possible choices for the type.

## The `#[dont_impl_for_bang]` attribute
## Opting-out

Even where it's possible to infer the impl for `!` there may be cases where
people don't want this behaviour. For example, someone might define a marker
trait `trait Marker { }` whose purpose is to only include some small class of
types, not including `!`. For these cases this RFC proposes adding a
`#[dont_impl_for_bang]` trait attribute used like this:
types, not including `!`. For these cases this RFC proposes allowing the
following to opt-out of automatically implementing a trait.

```rust
#[dont_impl_for_bang]
trait Marker {
}
impl !Marker for ! {}
```

# Drawbacks
[drawbacks]: #drawbacks

* Add's more complexity to the language and compiler.
* People who aren't aware of this feature might be surprised to learn that their
trait implements `!`. In most cases this won't be a huge problem since their
trait *should* implement `!`, however in the cases where it shouldn't they
will need to know about the likely-to-remain-obscure `#[dont_impl_for_bang]`
attribute to avoid it. At any rate, `!` is already a rather surprising type in
that it can magically transform into other types under the right conditions.
This is possible essentially because there is exactly one possible
implementation of `Into<T>` for `!` for all `T`, and the transformation only
occurs in dead code anyway. The author sees this RFC as a kind-of extension
of this behaviour.
* People who aren't aware of this feature might be surprised to learn that
their trait implements `!`. In most cases this won't be a huge problem since
Copy link
Member

Choose a reason for hiding this comment

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

Nit: "... to learn that ! implements their trait"

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks. Fixed.

their trait *should* implement `!`, however in the cases where it shouldn't
they will need to know to opt-out. At any rate, `!` is already a rather
surprising type in that it can magically transform into other types under the
right conditions. This is possible essentially because there is exactly one
possible implementation of `Into<T>` for `!` for all `T`, and the
transformation only occurs in dead code anyway. The author sees this RFC as
an extension in spirit of this behaviour.

# Alternatives
[alternatives]: #alternatives

* Not do this.
* Add an opt-in trait attribute instead.
Using a `#[derive_impl_for_bang]` attribute on traits which have an
inferable impl for `!` would be less cumbersome than writing these impls out
by hand. However it still comes with the problems of clutter and that most
traits could use this attribute but people won't think or won't bother to add
it.
* Add a way to opt-in to derivining impls instead. Using a `#[derive_impl(!)]`
attribute on traits which have an inferable impl for `!` would be less
cumbersome than writing these impls out by hand. However it still comes with
the problems of clutter and that most traits could use this attribute but
people won't think or won't bother to add it.

# Unresolved questions
[unresolved]: #unresolved-questions

Is there a more sensible name than`#[dont_impl_for_bang]`?
* None known