about summary refs log tree commit diff
path: root/compiler/rustc_mir_transform/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-11-23 02:03:50 +0000
committerbors <bors@rust-lang.org>2024-11-23 02:03:50 +0000
commit743003b1a6f838e0a694bd5824fd8a839d5d45e5 (patch)
tree8e461c2f51b33b32c04ac8dd01dcf00615e433e0 /compiler/rustc_mir_transform/src
parentf5be3ca1e35bbd504b3dea531dd15377c535f287 (diff)
parent69a38de97755780a5d78c655da2c953ba58ae18f (diff)
downloadrust-743003b1a6f838e0a694bd5824fd8a839d5d45e5.tar.gz
rust-743003b1a6f838e0a694bd5824fd8a839d5d45e5.zip
Auto merge of #132329 - compiler-errors:fn-and-destruct, r=lcnr
Implement `~const Destruct` effect goal in the new solver

This also fixed a subtle bug/limitation of the `NeedsConstDrop` check. Specifically, the "`Qualif`" API basically treats const drops as totally structural, even though dropping something that has an explicit `Drop` implementation cannot be structurally decomposed. For example:

```rust
#![feature(const_trait_impl)]

#[const_trait] trait Foo {
    fn foo();
}

struct Conditional<T: Foo>(T);

impl Foo for () {
    fn foo() {
        println!("uh oh");
    }
}

impl<T> const Drop for Conditional<T> where T: ~const Foo {
    fn drop(&mut self) {
        T::foo();
    }
}

const FOO: () = {
    let _ = Conditional(());
    //~^ This should error.
};

fn main() {}
```

In this example, when checking if the `Conditional(())` rvalue is const-drop, since `Conditional` has a const destructor, we would previously recurse into the `()` value and determine it has nothing to drop, which means that it is considered to *not* need a const drop -- even though dropping `Conditional(())` would mean evaluating the destructor which relies on that `T: const Foo` bound to hold!

This could be fixed alternatively by banning any const conditions on `const Drop` impls, but that really sucks -- that means that basically no *interesting* const drop impls could be written. We have the capability to totally and intuitively support the right behavior, which I've implemented here.
Diffstat (limited to 'compiler/rustc_mir_transform/src')
0 files changed, 0 insertions, 0 deletions