about summary refs log tree commit diff
path: root/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
diff options
context:
space:
mode:
authorDylan DPC <99973273+Dylan-DPC@users.noreply.github.com>2023-02-03 23:04:49 +0530
committerGitHub <noreply@github.com>2023-02-03 23:04:49 +0530
commit72213832f6d9601d1777491c4990724fd5e85146 (patch)
tree94a053116f1036348d12e5f91e8e32e26f1c48b9 /compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
parenta94b9fd0ace1336a3dd93f51f1c0db6ca0fd7f92 (diff)
parent4501d3abe17a3dc10f0dffcb38be04b58a33bafb (diff)
downloadrust-72213832f6d9601d1777491c4990724fd5e85146.tar.gz
rust-72213832f6d9601d1777491c4990724fd5e85146.zip
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 https://github.com/rust-lang/rust/pull/106604#issuecomment-1387353737.

**I propose making it legal to use autotraits as trait bounds on the `Self` type of trait methods in a trait object.** https://github.com/rust-lang/rust/issues/51443#issuecomment-1374847313 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 <https://github.com/rust-lang/rust/issues/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.

Fixes https://github.com/dtolnay/async-trait/issues/228.

r? `@lcnr`
Diffstat (limited to 'compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp')
0 files changed, 0 insertions, 0 deletions