You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Rollup merge of #107082 - dtolnay:autotraits, r=lcnr
Autotrait bounds on dyn-safe trait methods
This PR is a successor to #106604 implementing the approach encouraged by #106604 (comment).
**I propose making it legal to use autotraits as trait bounds on the `Self` type of trait methods in a trait object.** #51443 (comment) justifies why this use case is particularly important in the context of the async-trait crate.
```rust
#![feature(auto_traits)]
#![deny(where_clauses_object_safety)]
auto trait AutoTrait {}
trait MyTrait {
fn f(&self) where Self: AutoTrait;
}
fn main() {
let _: &dyn MyTrait;
}
```
Previously this would fail with:
```console
error: the trait `MyTrait` cannot be made into an object
--> src/main.rs:7:8
|
7 | fn f(&self) where Self: AutoTrait;
| ^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #51443 <#51443>
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> src/main.rs:7:8
|
6 | trait MyTrait {
| ------- this trait cannot be made into an object...
7 | fn f(&self) where Self: AutoTrait;
| ^ ...because method `f` references the `Self` type in its `where` clause
= help: consider moving `f` to another trait
```
In order for this to be sound without hitting #50781, **I further propose that we disallow handwritten autotrait impls that apply to trait objects.** Both of the following were previously allowed (_on nightly_) and no longer allowed in my proposal:
```rust
auto trait AutoTrait {}
trait MyTrait {}
impl AutoTrait for dyn MyTrait {} // NOT ALLOWED
impl<T: ?Sized> AutoTrait for T {} // NOT ALLOWED
```
(`impl<T> AutoTrait for T {}` remains allowed.)
After this change, traits with a default impl are implemented for a trait object **if and only if** the autotrait is one of the trait object's trait bounds (or a supertrait of a bound). In other words `dyn Trait + AutoTrait` always implements AutoTrait while `dyn Trait` never implements AutoTrait.
Fixesdtolnay/async-trait#228.
r? `@lcnr`
0 commit comments