Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Arbitrary self types v2: pointers feature gate. #129664

Merged

Conversation

adetaylor
Copy link
Contributor

The main arbitrary_self_types feature gate will shortly be reused for a new version of arbitrary self types which we are amending per this RFC. The main amendments are:

  • do support self types which can't safely implement Deref
  • do not support generic self types
  • do not support raw pointers as self types.

This PR relates to the last of those bullet points: this strips pointer support from the current arbitrary_self_types feature. We expect this to cause some amount of breakage for crates using this unstable feature to allow raw pointer self types. If that's the case, we want to know about it, and we want crate authors to know of the upcoming changes.

For now, this can be resolved by adding the new
arbitrary_self_types_pointers feature to such crates. If we determine that use of raw pointers as self types is common, then we may maintain that as an unstable feature even if we come to stabilize the rest of the arbitrary_self_types support in future. If we don't hear that this PR is causing breakage, then perhaps we don't need it at all, even behind an unstable feature gate.

Tracking issue

This is step 4 of the plan outlined here

@rustbot
Copy link
Collaborator

rustbot commented Aug 27, 2024

r? @fmease

rustbot has assigned @fmease.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Aug 27, 2024
@adetaylor
Copy link
Contributor Author

r? @wesleywiser but don't review it yet until I'm sure it passes tests

@rustbot rustbot assigned wesleywiser and unassigned fmease Aug 27, 2024
@rust-log-analyzer

This comment has been minimized.

The main `arbitrary_self_types` feature gate will shortly be reused for
a new version of arbitrary self types which we are amending per [this
RFC](https://github.com/rust-lang/rfcs/blob/master/text/3519-arbitrary-self-types-v2.md).
The main amendments are:

* _do_ support `self` types which can't safely implement `Deref`
* do _not_ support generic `self` types
* do _not_ support raw pointers as `self` types.

This PR relates to the last of those bullet points: this strips pointer
support from the current `arbitrary_self_types` feature.
We expect this to cause some amount of breakage for crates using this
unstable feature to allow raw pointer self types. If that's the case, we
want to know about it, and we want crate authors to know of the upcoming
changes.

For now, this can be resolved by adding the new
`arbitrary_self_types_pointers` feature to such crates. If we determine
that use of raw pointers as self types is common, then we may maintain
that as an unstable feature even if we come to stabilize the rest of the
`arbitrary_self_types` support in future. If we don't hear that this PR
is causing breakage, then perhaps we don't need it at all, even behind
an unstable feature gate.

[Tracking issue](rust-lang#44874)

This is [step 4 of the plan outlined here](rust-lang#44874 (comment))
@adetaylor adetaylor force-pushed the arbitrary-self-types-pointers-feature-gate branch from 6f31b93 to e77eb04 Compare August 27, 2024 17:32
@adetaylor adetaylor marked this pull request as ready for review August 28, 2024 08:54
@rustbot
Copy link
Collaborator

rustbot commented Aug 28, 2024

The Miri subtree was changed

cc @rust-lang/miri

@traviscross traviscross added the F-arbitrary_self_types `#![feature(arbitrary_self_types)]` label Aug 28, 2024
Copy link
Member

@wesleywiser wesleywiser left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a few minor suggestions 🙂

compiler/rustc_hir_analysis/src/check/wfcheck.rs Outdated Show resolved Hide resolved
compiler/rustc_hir_analysis/src/check/wfcheck.rs Outdated Show resolved Hide resolved
@wesleywiser
Copy link
Member

Looking at results for arbitrary_self_types on GH search, it seems the majority of hits are from forks of PyO3 (which mentions the feature in a comment, does not currently use it) and forks of rustc. Therefore, I don't think we need to worry too much about trying to migrate current users of the unstable feature to (potentially) the newly introduced pointer feature gate.

If you concur, I'm happy to r+!

@adetaylor

This comment was marked as resolved.

@adetaylor
Copy link
Contributor Author

OK, I've been told that it's pretty expensive to do a crater run and not all that useful for nightly-only breakage, so I'll take the r+ then!

@wesleywiser
Copy link
Member

We're right at the beginning of the release cycle so if there is unexpected, widespread breakage we have plenty of time to fix or revert before beta branches so I think this is the appropriate time to:

@bors r+

@bors
Copy link
Contributor

bors commented Sep 4, 2024

📌 Commit 8e20b66 has been approved by wesleywiser

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Sep 4, 2024
bors added a commit to rust-lang-ci/rust that referenced this pull request Sep 5, 2024
…iaskrgr

Rollup of 10 pull requests

Successful merges:

 - rust-lang#101339 (enable -Zrandomize-layout in debug CI builds )
 - rust-lang#120736 (rustdoc: add header map to the table of contents)
 - rust-lang#127021 (Add target support for RTEMS Arm)
 - rust-lang#128928 (CI: rfl: add more tools and steps)
 - rust-lang#129584 (warn the user if the upstream master branch is old)
 - rust-lang#129664 (Arbitrary self types v2: pointers feature gate.)
 - rust-lang#129752 (Make supertrait and implied predicates queries defaulted)
 - rust-lang#129918 (Update docs of `missing_abi` lint)
 - rust-lang#129919 (Stabilize `waker_getters`)
 - rust-lang#129925 (remove deprecated option `rust.split-debuginfo`)

Failed merges:

 - rust-lang#129789 (rustdoc: use strategic boxing to shrink `clean::Item`)

r? `@ghost`
`@rustbot` modify labels: rollup
bors added a commit to rust-lang-ci/rust that referenced this pull request Sep 5, 2024
…iaskrgr

Rollup of 10 pull requests

Successful merges:

 - rust-lang#101339 (enable -Zrandomize-layout in debug CI builds )
 - rust-lang#120736 (rustdoc: add header map to the table of contents)
 - rust-lang#127021 (Add target support for RTEMS Arm)
 - rust-lang#128928 (CI: rfl: add more tools and steps)
 - rust-lang#129584 (warn the user if the upstream master branch is old)
 - rust-lang#129664 (Arbitrary self types v2: pointers feature gate.)
 - rust-lang#129752 (Make supertrait and implied predicates queries defaulted)
 - rust-lang#129918 (Update docs of `missing_abi` lint)
 - rust-lang#129919 (Stabilize `waker_getters`)
 - rust-lang#129925 (remove deprecated option `rust.split-debuginfo`)

Failed merges:

 - rust-lang#129789 (rustdoc: use strategic boxing to shrink `clean::Item`)

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit 08187c3 into rust-lang:master Sep 5, 2024
6 checks passed
@rustbot rustbot added this to the 1.83.0 milestone Sep 5, 2024
rust-timer added a commit to rust-lang-ci/rust that referenced this pull request Sep 5, 2024
Rollup merge of rust-lang#129664 - adetaylor:arbitrary-self-types-pointers-feature-gate, r=wesleywiser

Arbitrary self types v2: pointers feature gate.

The main `arbitrary_self_types` feature gate will shortly be reused for a new version of arbitrary self types which we are amending per [this RFC](https://github.com/rust-lang/rfcs/blob/master/text/3519-arbitrary-self-types-v2.md). The main amendments are:

* _do_ support `self` types which can't safely implement `Deref`
* do _not_ support generic `self` types
* do _not_ support raw pointers as `self` types.

This PR relates to the last of those bullet points: this strips pointer support from the current `arbitrary_self_types` feature. We expect this to cause some amount of breakage for crates using this unstable feature to allow raw pointer self types. If that's the case, we want to know about it, and we want crate authors to know of the upcoming changes.

For now, this can be resolved by adding the new
`arbitrary_self_types_pointers` feature to such crates. If we determine that use of raw pointers as self types is common, then we may maintain that as an unstable feature even if we come to stabilize the rest of the `arbitrary_self_types` support in future. If we don't hear that this PR is causing breakage, then perhaps we don't need it at all, even behind an unstable feature gate.

[Tracking issue](rust-lang#44874)

This is [step 4 of the plan outlined here](rust-lang#44874 (comment))
@adetaylor
Copy link
Contributor Author

adetaylor commented Sep 6, 2024

This didn't work as planned - I'm seeing an unexpected error in one of my crates which relies upon the nightly arbitrary_self_types feature. I'm going to look into why, but we might need to revert this if a fix isn't immediately apparent. Looking into it now.

Phew, panic over. It's because I was doing a completely gross hack in autocxx to work around the absence of arbitrary self types, and it's expected that it broke.

In case anyone else hits the same thing, the gross hack was:

// CppRef<T> is some smart pointer type

impl<'a, T: ?Sized> Deref for CppRef<'a, T> {
    type Target = *const T;   // note the pointer type here
    #[inline]
    fn deref(&self) -> &Self::Target {
        // contents don't matter
    }
}

This hack tricked the deref algorithm to jumping from CppRef<T> to T without us having to have a UB-prone &T at any moment. This workaround obviously relied on the actual *const T dereferencing part of the former arbitrary self types work, which is just the bit we intentionally disabled in this PR. It's unsurprising that this broke.

@purplesyringa
Copy link

purplesyringa commented Sep 6, 2024

This broke crossmist. crossmist needs to serialize and deserialize objects all the time, including Box<dyn Trait>, sort of like serde_traitobject (after a quick look, that crait likely broke too).

While serializing through dyn Trait is easy if the trait contains something like a serialize_me method, deserializing requires somehow creating a valid fat pointer to call a method on from thin air. Both crossmist and serde_traitobject achieve this by storing a vtable pointer prior to object data during serialization, and invoke the virtual method on a dangling fat pointer (with the right vtable) during deserialization.

Crucially, this is only valid if pointers are used, not references, because references can't be dangling or null.

There are ways to workaround this, e.g. by using ZSTs or adding a fn get_deserializing_fn(&self) -> fn(&mut Deserializer) -> Self function to the trait and prepending the "deserializing fn" to data instead of the vtable. However, all these workarounds introduce indirection and slow code down when really the expected behavior is quite simple.

I think the breakage is going to be more significant than expected and I hope arbitrary_self_types_pointers is not removed.

purplesyringa added a commit to purplesyringa/crossmist that referenced this pull request Sep 6, 2024
@adetaylor
Copy link
Contributor Author

@purplesyringa thanks for the report, good to know. First off, from my side, there's no particular pressure to remove arbitrary_self_types_pointers, it's just that we're hoping to eventually stabilize the rest of arbitrary self types, so that's why it's been split into a separate unstable feature gate. Others may have different views, but that's my current understanding.

Maybe your use-case could be accommodated using "regular" arbitrary_self_types by transmuting your fat pointer into a transparent newtype wrapper which implements the upcoming Receiver trait, and then using that as the receiver? But maybe not if you're trying to call existing functions on existing types, and don't have an opportunity to insert an additional type wrapper.

@purplesyringa
Copy link

purplesyringa commented Sep 6, 2024

Sure, I just saw this in the OP and thought I should weigh in to prevent this outcome:

If we don't hear that this PR is causing breakage, then perhaps we don't need it at all, even behind an unstable feature gate.


Wrapping the fat pointer in a newtype is fine, the more troublesome part is object safety. The method fn deserialize_me(self: NewTypeWrapper<Self>) would have to be callable via Self as Deserialize's vtable. This interacts with DispatchFromDyn, which I'm unfamiliar with, and it's not 100% clear to me how stable it is to stabilization and if I can easily wrap a raw pointer using it.

@adetaylor
Copy link
Contributor Author

DispatchFromDyn is on its way to partial stabilization via the #[derive(SmartPointer)] work in case that works for you?

@purplesyringa
Copy link

It might work, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
F-arbitrary_self_types `#![feature(arbitrary_self_types)]` S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants