Conversation
|
r? @oli-obk rustbot has assigned @oli-obk. Use Why was this reviewer chosen?The reviewer was selected based on:
|
| /// | ||
| /// We already emit errors for the case where the impossible bound exists only on the self ty, or | ||
| /// only on the impl(s). | ||
| pub(crate) fn is_impossible_self_ty(tcx: TyCtxt<'_>, adt_did: LocalDefId) -> bool { |
There was a problem hiding this comment.
I basically lifted this logic wholesale from the is_impossible_associated_item query, though I couldn't really find a nice way to make them into a single shared thing, since is_impossible_associated_item filters the obligations to those that only mention the parent item's generics before registering them with the ocx.
This comment has been minimized.
This comment has been minimized.
a624c3c to
cd2a97d
Compare
|
This PR changes a file inside |
|
#150387 may keep existing. Can it be reproed with just specialization and no impossible bounds? |
This comment has been minimized.
This comment has been minimized.
I don't think one exists if you only use specialization and nothing else, but this program does ICE with const drop, so I've removed that issue from the PR description: #![feature(min_specialization, const_trait_impl, const_destruct)]
struct Thing;
impl Drop for Thing { default fn drop(&mut self) {} }
const impl Drop for Thing { fn drop(&mut self) {} }since the const impl specializes the non-const one, and none of them break dropck's rules, so we get a delayed bug :D |
cd2a97d to
11c2b3d
Compare
|
This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed. Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers. |
😨 Aaaaa Nice find |
|
@bors r+ |
…i-obk
don't calculate dtors if the self ty has impossible bounds
If we have multiple drop impls and a self ty that all have the same impossible bounds, we end up with duplicate `drop`s with different `DefId`s, which causes us to ICE with a delayed bug in `calculate_dtor`. Coherence accepts these impls since they have impossible bounds, and nothing else in `check_drop_impl` checks this, leading to us accepting the code and subsequently ICEing from the delayed bug.
We now skip considering the current drop impl as a dtor candidate if the self ty and impl(s) have the same impossible bounds, since if the self ty is unnameable, it's impossible to construct an instance in the first place. Checking only the self ty is sufficient here, as `check_drop_impl` checks the case where the impossible bounds exist only on the drop impl, and we're not allowed in general to have a struct whose bounds are more restrictive than its impl's, so the only case we're currently missing is the case where the self ty and the `Drop` impls have the exact same impossible bounds.
My reasoning for accepting such code instead of emitting an error is that, in general, we allow users to write code with impossible or trivial bounds, so long as they never try to actually name or run that code. This PR makes `Drop` behave the same way.
This results in overlapping impossible drop impls behaving like other traits: for instance, the following compiles on nightly today:
```rs
pub trait Foo {
fn foo(&self) {}
}
pub struct Thing<T>(T)
where
[T]: Sized;
impl<T> Foo for Thing<T> where [T]: Sized {}
impl<T> Foo for Thing<T> where [T]: Sized {} // removing this impl is ok as well
```
Although this ICE only seems to be reachable for sync drop, not making the same change for async drop makes the following program, which currently compiles on nightly, stop compiling:
```rs
#![feature(async_drop)]
use core::future::AsyncDrop;
use core::pin::Pin;
pub struct Thing<T>(T) where [T]: Sized;
impl<T> Drop for Thing<T> where [T]: Sized {
fn drop(&mut self) {}
}
impl<T> AsyncDrop for Thing<T> where [T]: Sized {
async fn drop(self: Pin<&mut Self>) {}
}
```
which feels like something we don't want.
cc rust-lang#159118 (comment)
fixes rust-lang#153947
…i-obk
don't calculate dtors if the self ty has impossible bounds
If we have multiple drop impls and a self ty that all have the same impossible bounds, we end up with duplicate `drop`s with different `DefId`s, which causes us to ICE with a delayed bug in `calculate_dtor`. Coherence accepts these impls since they have impossible bounds, and nothing else in `check_drop_impl` checks this, leading to us accepting the code and subsequently ICEing from the delayed bug.
We now skip considering the current drop impl as a dtor candidate if the self ty and impl(s) have the same impossible bounds, since if the self ty is unnameable, it's impossible to construct an instance in the first place. Checking only the self ty is sufficient here, as `check_drop_impl` checks the case where the impossible bounds exist only on the drop impl, and we're not allowed in general to have a struct whose bounds are more restrictive than its impl's, so the only case we're currently missing is the case where the self ty and the `Drop` impls have the exact same impossible bounds.
My reasoning for accepting such code instead of emitting an error is that, in general, we allow users to write code with impossible or trivial bounds, so long as they never try to actually name or run that code. This PR makes `Drop` behave the same way.
This results in overlapping impossible drop impls behaving like other traits: for instance, the following compiles on nightly today:
```rs
pub trait Foo {
fn foo(&self) {}
}
pub struct Thing<T>(T)
where
[T]: Sized;
impl<T> Foo for Thing<T> where [T]: Sized {}
impl<T> Foo for Thing<T> where [T]: Sized {} // removing this impl is ok as well
```
Although this ICE only seems to be reachable for sync drop, not making the same change for async drop makes the following program, which currently compiles on nightly, stop compiling:
```rs
#![feature(async_drop)]
use core::future::AsyncDrop;
use core::pin::Pin;
pub struct Thing<T>(T) where [T]: Sized;
impl<T> Drop for Thing<T> where [T]: Sized {
fn drop(&mut self) {}
}
impl<T> AsyncDrop for Thing<T> where [T]: Sized {
async fn drop(self: Pin<&mut Self>) {}
}
```
which feels like something we don't want.
cc rust-lang#159118 (comment)
fixes rust-lang#153947
…uwer Rollup of 20 pull requests Successful merges: - #160401 (sparc: make ABI consistent with clang) - #162715 (don't calculate dtors if the self ty has impossible bounds) - #162740 (stdarch subtree update) - #162824 (link Enzyme and the offload with in-tree lld if possible) - #162946 (Simplify query stack printing) - #161005 (fix: unfulfilled nested dead code lint) - #161246 (Normalize non-rigid aliases in ty_known_to_outlive) - #161803 (Fix docs of make_ascii_lowercase/make_ascii_upercase) - #162256 (Add mentions to sync back `RELEASES.md` to the `main` branch) - #162661 (simplify `Target::GenericParam`) - #162666 (Tidy footnote in `platform-support.md`) - #162803 (docs(num): add documentation for `NonZero::from_str`) - #162879 (use u64 limbs in core::num::bignum) - #162903 (PassWrapper: adapt to LLVM reading exception model from module flag) - #162905 (c-variadic: add checks for windows i686) - #162906 (Move more `rustdoc-html` tests in the right location) - #162922 (An assortment of polonius tweaks) - #162929 (Update unicode_data to Unicode version 18.0.0) - #162930 (Use niche length type for strlen to guarantee `isize::MAX` bound) - #162960 (Guard types with unstable `Allocator` params ahead of partial stabilization)
…i-obk
don't calculate dtors if the self ty has impossible bounds
If we have multiple drop impls and a self ty that all have the same impossible bounds, we end up with duplicate `drop`s with different `DefId`s, which causes us to ICE with a delayed bug in `calculate_dtor`. Coherence accepts these impls since they have impossible bounds, and nothing else in `check_drop_impl` checks this, leading to us accepting the code and subsequently ICEing from the delayed bug.
We now skip considering the current drop impl as a dtor candidate if the self ty and impl(s) have the same impossible bounds, since if the self ty is unnameable, it's impossible to construct an instance in the first place. Checking only the self ty is sufficient here, as `check_drop_impl` checks the case where the impossible bounds exist only on the drop impl, and we're not allowed in general to have a struct whose bounds are more restrictive than its impl's, so the only case we're currently missing is the case where the self ty and the `Drop` impls have the exact same impossible bounds.
My reasoning for accepting such code instead of emitting an error is that, in general, we allow users to write code with impossible or trivial bounds, so long as they never try to actually name or run that code. This PR makes `Drop` behave the same way.
This results in overlapping impossible drop impls behaving like other traits: for instance, the following compiles on nightly today:
```rs
pub trait Foo {
fn foo(&self) {}
}
pub struct Thing<T>(T)
where
[T]: Sized;
impl<T> Foo for Thing<T> where [T]: Sized {}
impl<T> Foo for Thing<T> where [T]: Sized {} // removing this impl is ok as well
```
Although this ICE only seems to be reachable for sync drop, not making the same change for async drop makes the following program, which currently compiles on nightly, stop compiling:
```rs
#![feature(async_drop)]
use core::future::AsyncDrop;
use core::pin::Pin;
pub struct Thing<T>(T) where [T]: Sized;
impl<T> Drop for Thing<T> where [T]: Sized {
fn drop(&mut self) {}
}
impl<T> AsyncDrop for Thing<T> where [T]: Sized {
async fn drop(self: Pin<&mut Self>) {}
}
```
which feels like something we don't want.
cc rust-lang#159118 (comment)
fixes rust-lang#153947
…uwer Rollup of 19 pull requests Successful merges: - #160401 (sparc: make ABI consistent with clang) - #162715 (don't calculate dtors if the self ty has impossible bounds) - #162740 (stdarch subtree update) - #162946 (Simplify query stack printing) - #161005 (fix: unfulfilled nested dead code lint) - #161246 (Normalize non-rigid aliases in ty_known_to_outlive) - #161803 (Fix docs of make_ascii_lowercase/make_ascii_upercase) - #162256 (Add mentions to sync back `RELEASES.md` to the `main` branch) - #162661 (simplify `Target::GenericParam`) - #162666 (Tidy footnote in `platform-support.md`) - #162803 (docs(num): add documentation for `NonZero::from_str`) - #162879 (use u64 limbs in core::num::bignum) - #162903 (PassWrapper: adapt to LLVM reading exception model from module flag) - #162905 (c-variadic: add checks for windows i686) - #162906 (Move more `rustdoc-html` tests in the right location) - #162922 (An assortment of polonius tweaks) - #162929 (Update unicode_data to Unicode version 18.0.0) - #162930 (Use niche length type for strlen to guarantee `isize::MAX` bound) - #162960 (Guard types with unstable `Allocator` params ahead of partial stabilization)
…uwer Rollup of 19 pull requests Successful merges: - #160401 (sparc: make ABI consistent with clang) - #162715 (don't calculate dtors if the self ty has impossible bounds) - #162740 (stdarch subtree update) - #162946 (Simplify query stack printing) - #161005 (fix: unfulfilled nested dead code lint) - #161246 (Normalize non-rigid aliases in ty_known_to_outlive) - #161803 (Fix docs of make_ascii_lowercase/make_ascii_upercase) - #162256 (Add mentions to sync back `RELEASES.md` to the `main` branch) - #162661 (simplify `Target::GenericParam`) - #162666 (Tidy footnote in `platform-support.md`) - #162803 (docs(num): add documentation for `NonZero::from_str`) - #162879 (use u64 limbs in core::num::bignum) - #162903 (PassWrapper: adapt to LLVM reading exception model from module flag) - #162905 (c-variadic: add checks for windows i686) - #162906 (Move more `rustdoc-html` tests in the right location) - #162922 (An assortment of polonius tweaks) - #162929 (Update unicode_data to Unicode version 18.0.0) - #162930 (Use niche length type for strlen to guarantee `isize::MAX` bound) - #162960 (Guard types with unstable `Allocator` params ahead of partial stabilization)
If we have multiple drop impls and a self ty that all have the same impossible bounds, we end up with duplicate
drops with differentDefIds, which causes us to ICE with a delayed bug incalculate_dtor. Coherence accepts these impls since they have impossible bounds, and nothing else incheck_drop_implchecks this, leading to us accepting the code and subsequently ICEing from the delayed bug.We now skip considering the current drop impl as a dtor candidate if the self ty and impl(s) have the same impossible bounds, since if the self ty is unnameable, it's impossible to construct an instance in the first place. Checking only the self ty is sufficient here, as
check_drop_implchecks the case where the impossible bounds exist only on the drop impl, and we're not allowed in general to have a struct whose bounds are more restrictive than its impl's, so the only case we're currently missing is the case where the self ty and theDropimpls have the exact same impossible bounds.My reasoning for accepting such code instead of emitting an error is that, in general, we allow users to write code with impossible or trivial bounds, so long as they never try to actually name or run that code. This PR makes
Dropbehave the same way.This results in overlapping impossible drop impls behaving like other traits: for instance, the following compiles on nightly today:
Although this ICE only seems to be reachable for sync drop, not making the same change for async drop makes the following program, which currently compiles on nightly, stop compiling:
which feels like something we don't want.
cc #159118 (comment)
fixes #153947