about summary refs log tree commit diff
path: root/compiler/rustc_llvm/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-06-04 02:34:20 +0000
committerbors <bors@rust-lang.org>2024-06-04 02:34:20 +0000
commit90d6255d82dcfd0b73dbaa4f172a7f9886dcc2c1 (patch)
tree09d35de25a3e626493980f7cee0c26e59286a2b8 /compiler/rustc_llvm/src
parent1689a5a531f1fe404944ed8c3ac6cb85a2cff7e0 (diff)
parent511f1cf7c8e96c2350dac7b4870e92c99ee08b92 (diff)
downloadrust-90d6255d82dcfd0b73dbaa4f172a7f9886dcc2c1.tar.gz
rust-90d6255d82dcfd0b73dbaa4f172a7f9886dcc2c1.zip
Auto merge of #125380 - compiler-errors:wc-obj-safety, r=oli-obk
Make `WHERE_CLAUSES_OBJECT_SAFETY` a regular object safety violation

#### The issue

In #50781, we have known about unsound `where` clauses in function arguments:

```rust
trait Impossible {}

trait Foo {
    fn impossible(&self)
    where
        Self: Impossible;
}

impl Foo for &() {
    fn impossible(&self)
    where
        Self: Impossible,
    {}
}

// `where` clause satisfied for the object, meaning that the function now *looks* callable.
impl Impossible for dyn Foo {}

fn main() {
    let x: &dyn Foo = &&();
    x.impossible();
}
```

... which currently segfaults at runtime because we try to call a method in the vtable that doesn't exist. :(

#### What did u change

This PR removes the `WHERE_CLAUSES_OBJECT_SAFETY` lint and instead makes it a regular object safety violation. I choose to make this into a hard error immediately rather than a `deny` because of the time that has passed since this lint was authored, and the single (1) regression (see below).

That means that it's OK to mention `where Self: Trait` where clauses in your trait, but making such a trait into a `dyn Trait` object will report an object safety violation just like `where Self: Sized`, etc.

```rust
trait Impossible {}

trait Foo {
    fn impossible(&self)
    where
        Self: Impossible; // <~ This definition is valid, just not object-safe.
}

impl Foo for &() {
    fn impossible(&self)
    where
        Self: Impossible,
    {}
}

fn main() {
    let x: &dyn Foo = &&(); // <~ THIS is where we emit an error.
}
```

#### Regressions

From a recent crater run, there's only one crate that relies on this behavior: https://github.com/rust-lang/rust/pull/124305#issuecomment-2122381740. The crate looks unmaintained and there seems to be no dependents.

#### Further

We may later choose to relax this (e.g. when the where clause is implied by the supertraits of the trait or something), but this is not something I propose to do in this FCP.

For example, given:

```
trait Tr {
  fn f(&self) where Self: Blanket;
}

impl<T: ?Sized> Blanket for T {}
```

Proving that some placeholder `S` implements `S: Blanket` would be sufficient to prove that the same (blanket) impl applies for both `Concerete: Blanket` and `dyn Trait: Blanket`.

Repeating here that I don't think we need to implement this behavior right now.

----

r? lcnr
Diffstat (limited to 'compiler/rustc_llvm/src')
0 files changed, 0 insertions, 0 deletions