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

Tracking issue for RFC 3519: arbitrary_self_types #44874

Open
7 of 15 tasks
Tracked by #165
arielb1 opened this issue Sep 26, 2017 · 148 comments
Open
7 of 15 tasks
Tracked by #165

Tracking issue for RFC 3519: arbitrary_self_types #44874

arielb1 opened this issue Sep 26, 2017 · 148 comments
Labels
B-RFC-approved Blocker: Approved by a merged RFC but not yet implemented. B-unstable Blocker: Implemented in the nightly compiler and unstable. C-tracking-issue Category: An issue tracking the progress of sth. like the implementation of an RFC F-arbitrary_self_types `#![feature(arbitrary_self_types)]` S-tracking-needs-summary Status: It's hard to tell what's been done and what hasn't! Someone should do some investigation. S-types-deferred Status: Identified as a valid potential future enhancement that is not currently being worked on T-lang Relevant to the language team, which will review and decide on the PR/issue. T-types Relevant to the types team, which will review and decide on the PR/issue.

Comments

@arielb1
Copy link
Contributor

arielb1 commented Sep 26, 2017

This is the tracking issue for RFC 3519: Arbitrary self types v2.

The feature gate for this issue is #![feature(arbitrary_self_types)].

About tracking issues

Tracking issues are used to record the overall progress of implementation. They are also used as hubs connecting to other relevant issues, e.g., bugs or open design questions. A tracking issue is however not meant for large scale discussion, questions, or bug reports about a feature. Instead, open a dedicated issue for the specific matter and add the relevant feature gate label.

Steps

Current plan is:

  • Fix the current lifetime elision bugs
  • Search for potentially conflicting method candidates
  • Block generic arbitrary self types.
  • Introduce an arbitrary_self_types_pointers feature gate
  • Rename the old Receiver trait -- currently being run through crater
  • Land the new Receiver trait without it doing anything.
  • Switch over the method resolution to use the Receiver trait, if the arbitrary_self_types feature is enabled. The main event.
  • Add diagnostics for the !Sized case and the NonNull etc. cases.
  • Update the Rust reference.
  • Add documentation to the dev guide. See the instructions.
  • Add formatting for new syntax to the style guide. See the nightly style procedure.
  • Stabilize!

Unresolved Questions

None.

Notable for Stabilization

Related

Implementation history

TODO.


(Below follows content that predated the accepted Arbitrary Self Types v2 RFC.)

  • figure out the object safety situation
  • figure out the handling of inference variables behind raw pointers
  • decide whether we want safe virtual raw pointer methods

Object Safety

See #27941 (comment)

Handling of inference variables

Calling a method on *const _ could now pick impls of the form

impl RandomType {
    fn foo(*const Self) {}
}

Because method dispatch wants to be "limited", this won't really work, and as with the existing situation on &_ we should be emitting an "the type of this value must be known in this context" error.

This feels like fairly standard inference breakage, but we need to check the impact of this before proceeding.

Safe virtual raw pointer methods

e.g. this is UB, so we might want to force the call <dyn Foo as Foo>::bar to be unsafe somehow - e.g. by not allowing dyn Foo to be object safe unless bar was an unsafe fn

trait Foo {
    fn bar(self: *const Self);
}

fn main() {
    // creates a raw pointer with a garbage vtable
    let foo: *const dyn Foo = unsafe { mem::transmute([0usize, 0x1000usize]) };
    // and call it
    foo.bar(); // this is UB
}

However, even today you could UB in safe code with mem::size_of_val(foo) on the above code, so this might not be actually a problem.

More information

There's no reason the self syntax has to be restricted to &T, &mut T and Box<T>, we should allow for more types there, e.g.

trait MyStuff {
    fn do_async_task(self: Rc<Self>);
}

impl MyStuff for () {
    fn do_async_task(self: Rc<Self>) {
        // ...
    }
}

Rc::new(()).do_async_stuff();
@arielb1 arielb1 changed the title Allow methods with arbitrary self-types Allow trait methods with arbitrary self-types Sep 26, 2017
@aidanhs aidanhs added the C-feature-request Category: A feature request, i.e: not implemented / a PR. label Sep 28, 2017
@porky11
Copy link

porky11 commented Sep 28, 2017

Why would you need this?
Why wouldn't you write an impl like this:

impl MyStuff for Rc<()> {
    fn do_async_task(self) {
        // ...
    }
}

I'd rather define the trait different. Maybe like this:

trait MyStuff: Rc {
    fn do_async_task(self);
}

In this case, Rc would be a trait type. If every generic type implemented a specific trait (this could be implemented automatically for generic types) this seems more understandable to me.

@cuviper
Copy link
Member

cuviper commented Sep 28, 2017

This could only be allowed for trait methods, right?

For inherent methods, I can't impl Rc<MyType>, but if impl MyType can add methods with self: Rc<Self>, it seems like that would enable weird method shadowing.

@arielb1
Copy link
Contributor Author

arielb1 commented Oct 1, 2017

@cuviper

This is still pending lang team decisions (I hope there will be at least 1 RFC) but I think it will only be allowed for trait method impls.

@arielb1
Copy link
Contributor Author

arielb1 commented Oct 1, 2017

@porky11

You can't implement anything for Rc<YourType> from a crate that does not own the trait.

@arielb1
Copy link
Contributor Author

arielb1 commented Oct 2, 2017

So changes needed:

  • remove the current error message for trait methods only, but still have a feature gate.
  • make sure fn(self: Rc<Self>) doesn't accidentally become object-safe
  • make sure method dispatch woks for Rc<Self> methods
  • add tests

@arielb1 arielb1 added E-mentor Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion. and removed E-needs-mentor labels Oct 2, 2017
@SimonSapin
Copy link
Contributor

I’ll look into this.

@arielb1
Copy link
Contributor Author

arielb1 commented Oct 2, 2017

Note that this is only supported to work with trait methods (and trait impl methods), aka

trait Foo {
    fn foo(self: Rc<Self>);
}
impl Foo for () {
    fn foo(self: Rc<Self>) {}
}

and is NOT supposed to work for inherent impl methods:

struct Foo;
impl Foo {
    fn foo(self: Rc<Self>) {}
}

@SimonSapin
Copy link
Contributor

I got caught in some more Stylo work that's gonna take a while, so if someone else wants to work on this in the meantime feel free.

@kennytm
Copy link
Member

kennytm commented Oct 6, 2017

Is this supposed to allow any type as long as it involves Self? Or must it impl Deref<Target=Self>?

trait MyStuff {
    fn a(self: Option<Self>);
    fn b(self: Result<Self, Self>);
    fn c(self: (Self, Self, Self));
    fn d(self: Box<Box<Self>>);
}

impl MyStuff for i32 {
   ...
}

Some(1).a();  // ok?
Ok(2).b();  // ok?
(3, 4, 5).c(); // ok?
(box box 6).d(); // ok?

kennytm added a commit to kennytm/rust that referenced this issue Oct 10, 2017
…ents, r=nikomatsakis

Update comments referring to old check_method_self_type

I was browsing the code base, trying to figure out how rust-lang#44874 could be implemented, and noticed some comments that were out of date and a bit misleading (`check_method_self_type` has since been renamed to `check_method_receiver`). Thought it would be an easy first contribution to Rust!
@mikeyhew
Copy link
Contributor

I've started working on this issue. You can see my progress on this branch

@mikeyhew
Copy link
Contributor

mikeyhew commented Nov 2, 2017

@arielb1 You seem adamant that this should only be allowed for traits and not structs. Aside from method shadowing, are there other concerns?

@arielb1
Copy link
Contributor Author

arielb1 commented Nov 2, 2017

@mikeyhew

inherent impl methods are loaded based on the type. You shouldn't be able to add a method to Rc<YourType> that is usable without any use statement.

@arielb1
Copy link
Contributor Author

arielb1 commented Nov 2, 2017

That's it, if you write something like

trait Foo {
    fn bar(self: Rc<Self>);
}

Then it can only be used if the trait Foo is in-scope. Even if you do something like fn baz(self: u32); that only works for modules that use the trait.

If you write an inherent impl, then it can be called without having the trait in-scope, which means we have to be more careful to not allow these sorts of things.

@mikeyhew
Copy link
Contributor

mikeyhew commented Nov 3, 2017

@arielb1 Can you give an example of what we want to avoid? I'm afraid I don't really see what the issue is. A method you define to take &self will still be callable on Rc<Self>, the same as if you define it to take self: Rc<Self>. And the latter only affectsRc<MyStruct>, not Rc<T> in general.

@mikeyhew
Copy link
Contributor

mikeyhew commented Nov 4, 2017

I've been trying to figure out how we can support dynamic dispatch with arbitrary self types. Basically we need a way to take a CustomPointer<Trait>, and do two things: (1) extract the vtable, so we can call the method, and (2) turn it into a CustomPointer<T> without knowing T.

(1) is pretty straightforward: call Deref::deref and extract the vtable from that. For (2), we'll effectively need to do the opposite of how unsized coercions are implemented for ADTs. We don't know T, but we can can coerce to CustomPointer<()>, assuming CustomPointer<()> has the same layout as CustomPointer<T> for all T: Sized. (Is that true?)

The tough question is, how do we get the type CustomPointer<()>? It looks simple in this case, but what if CustomPointer had multiple type parameters and we had a CustomPointer<Trait, Trait>? Which type parameter do we switch with ()? In the case of unsized coercions, it's easy, because the type to coerce to is given to us. Here, though, we're on our own.

@arielb1 @nikomatsakis any thoughts?

@nikomatsakis
Copy link
Contributor

@arielb1

and is NOT supposed to work for inherent impl methods:

Wait, why do you not want it work for inherent impl methods? Because of scoping? I'm confused. =)

@nikomatsakis
Copy link
Contributor

@mikeyhew

I've been trying to figure out how we can support dynamic dispatch with arbitrary self types.

I do want to support that, but I expected it to be out of scope for this first cut. That is, I expected that if a trait uses anything other than self, &self, &mut self, or self: Box<Self> it would be considered no longer object safe.

@mikeyhew
Copy link
Contributor

mikeyhew commented Nov 4, 2017

@nikomatsakis

I do want to support that, but I expected it to be out of scope for this first cut.

I know, but I couldn't help looking into it, it's all very interesting to me :)

@arielb1
Copy link
Contributor Author

arielb1 commented Nov 5, 2017

Wait, why do you not want it work for inherent impl methods? Because of scoping? I'm confused. =)

We need some sort of "orphan rule" to at least prevent people from doing things like this:

struct Foo;
impl Foo {
    fn frobnicate<T>(self: Vec<T>, x: Self) { /* ... */ }
}

Because then every crate in the world can call my_vec.frobnicate(...); without importing anything, so if 2 crates do this there's a conflict when we link them together.

Maybe the best way to solve this would be to require self to be a "thin pointer to Self" in some way (we can't use Deref alone because it doesn't allow for raw pointers - but Deref + deref of raw pointers, or eventually an UnsafeDeref trait that reifies that - would be fine).

I think that if we have the deref-back requirement, there's no problem with allowing inherent methods - we just need to change inherent method search a bit to also look at defids of derefs. So that's probably a better idea than restricting to trait methods only.

Note that the CoerceSized restriction for object safety is orthogonal if we want allocators:

struct Foo;
impl Tr for Foo {
    fn frobnicate<A: Allocator+?Sized>(self: RcWithAllocator<Self, A>) { /* ... */ }
}

Where an RcWithAllocator<Self, A> can be converted to a doubly-fat RcWithAllocator<Tr, Allocator>.

@mikeyhew
Copy link
Contributor

mikeyhew commented Nov 5, 2017

@arielb1

Because then every crate in the world can call my_vec.frobnicate(...); without importing anything, so if 2 crates do this there's a conflict when we link them together.

Are saying is that there would be a "conflicting symbols for architechture x86_64..." linker error?

Maybe the best way to solve this would be to require self to be a "thin pointer to Self" in some way (we can't use Deref alone because it doesn't allow for raw pointers - but Deref + deref of raw pointers, or eventually an UnsafeDeref trait that reifies that - would be fine).

I'm confused, are you still talking about frobnicate here, or have you moved on to the vtable stuff?

@arielb1
Copy link
Contributor Author

arielb1 commented Nov 5, 2017

I'm confused, are you still talking about frobnicate here, or have you moved on to the vtable stuff?

The deref-back requirement is supposed to be for everything, not only object-safety. It prevents the problem when one person does

struct MyType;
impl MyType {
    fn foo<T>(self: Vec<(MyType, T)>) { /* ... */ }
}   

While another person does

struct OurType;
impl OurType {
    fn foo<T>(self: Vec<(T, OurType)>) {/* ... */ }
}   

And now you have a conflict on Vec<(MyType, OurType)>. If you include the deref-back requirement, there is no problem with allowing inherent impls.

@adetaylor
Copy link
Contributor

adetaylor commented Dec 19, 2024

A further update on item 9, documentation. All the following PRs are draft and not yet for review, but linking them from here for awareness:

In the process of preparing these docs, I found a creative, cunning and implausible way to trigger the new deshadowing code without enabling the arbitrary_self_types feature. This wasn't intentional so this is fixed in #134524.

jhpratt added a commit to jhpratt/rust that referenced this issue Dec 20, 2024
Arbitrary self types v2: roll loop.

Just for slightly more concise code - no functional changes.

r? `@wesleywiser`

Part of rust-lang#44874
rust-timer added a commit to rust-lang-ci/rust that referenced this issue Dec 20, 2024
Rollup merge of rust-lang#134521 - adetaylor:roll-loop, r=wesleywiser

Arbitrary self types v2: roll loop.

Just for slightly more concise code - no functional changes.

r? `@wesleywiser`

Part of rust-lang#44874
jieyouxu added a commit to jieyouxu/rust that referenced this issue Dec 20, 2024
… r=wesleywiser

Arbitrary self types v2: niche deshadowing test

Arbitrary self types v2 attempts to detect cases where methods in an "outer" type (e.g. a smart pointer) might "shadow" methods in the referent.

There are a couple of cases where the current code makes no attempt to detect such shadowing. Both of these cases only apply if other unstable features are enabled.

Add a test, mostly for illustrative purposes, so we can see the shadowing cases that can occur.

Part of rust-lang#44874
r? `@wesleywiser`
jieyouxu added a commit to jieyouxu/rust that referenced this issue Dec 20, 2024
… r=wesleywiser

Arbitrary self types v2: niche deshadowing test

Arbitrary self types v2 attempts to detect cases where methods in an "outer" type (e.g. a smart pointer) might "shadow" methods in the referent.

There are a couple of cases where the current code makes no attempt to detect such shadowing. Both of these cases only apply if other unstable features are enabled.

Add a test, mostly for illustrative purposes, so we can see the shadowing cases that can occur.

Part of rust-lang#44874
r? ``@wesleywiser``
jieyouxu added a commit to jieyouxu/rust that referenced this issue Dec 20, 2024
Arbitrary self types v2: no deshadow pre feature.

The arbitrary self types v2 work introduces a check for shadowed methods, whereby a method in some "outer" smart pointer type may called in preference to a method in the inner referent. This is bad if the outer pointer adds a method later, as it may change behavior, so we ensure we error in this circumstance.

It was intended that this new shadowing detection system only comes into play for users who enable the `arbitrary_self_types` feature (or of course everyone later if it's stabilized). It was believed that the new deshadowing code couldn't be reached without building the custom smart pointers that `arbitrary_self_types` enables, and therefore there was no risk of this code impacting existing users.

However, it turns out that cunning use of `Pin::get_ref` can cause this type of shadowing error to be emitted now. This commit adds a test for this case.

As we want this test to pass without arbitrary_self_types, but fail with it, I've split it into two files (one with run-pass and one without). If there's a better way I can amend it.

Part of rust-lang#44874

r? ``@wesleywiser``
@chriskrycho
Copy link
Contributor

Just for visibility to the team, see my comment on the PR for this in The Book. Short version: not yet sure if it fits in The Book at all, and if it does we’ll need to think about where and how to make it fit! Happy to discuss further… but probably after the holidays!

matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Dec 21, 2024
… r=wesleywiser

Arbitrary self types v2: niche deshadowing test

Arbitrary self types v2 attempts to detect cases where methods in an "outer" type (e.g. a smart pointer) might "shadow" methods in the referent.

There are a couple of cases where the current code makes no attempt to detect such shadowing. Both of these cases only apply if other unstable features are enabled.

Add a test, mostly for illustrative purposes, so we can see the shadowing cases that can occur.

Part of rust-lang#44874
r? ```@wesleywiser```
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Dec 21, 2024
Arbitrary self types v2: no deshadow pre feature.

The arbitrary self types v2 work introduces a check for shadowed methods, whereby a method in some "outer" smart pointer type may called in preference to a method in the inner referent. This is bad if the outer pointer adds a method later, as it may change behavior, so we ensure we error in this circumstance.

It was intended that this new shadowing detection system only comes into play for users who enable the `arbitrary_self_types` feature (or of course everyone later if it's stabilized). It was believed that the new deshadowing code couldn't be reached without building the custom smart pointers that `arbitrary_self_types` enables, and therefore there was no risk of this code impacting existing users.

However, it turns out that cunning use of `Pin::get_ref` can cause this type of shadowing error to be emitted now. This commit adds a test for this case.

As we want this test to pass without arbitrary_self_types, but fail with it, I've split it into two files (one with run-pass and one without). If there's a better way I can amend it.

Part of rust-lang#44874

r? ```@wesleywiser```
rust-timer added a commit to rust-lang-ci/rust that referenced this issue Dec 21, 2024
Rollup merge of rust-lang#134524 - adetaylor:getref, r=compiler-errors

Arbitrary self types v2: no deshadow pre feature.

The arbitrary self types v2 work introduces a check for shadowed methods, whereby a method in some "outer" smart pointer type may called in preference to a method in the inner referent. This is bad if the outer pointer adds a method later, as it may change behavior, so we ensure we error in this circumstance.

It was intended that this new shadowing detection system only comes into play for users who enable the `arbitrary_self_types` feature (or of course everyone later if it's stabilized). It was believed that the new deshadowing code couldn't be reached without building the custom smart pointers that `arbitrary_self_types` enables, and therefore there was no risk of this code impacting existing users.

However, it turns out that cunning use of `Pin::get_ref` can cause this type of shadowing error to be emitted now. This commit adds a test for this case.

As we want this test to pass without arbitrary_self_types, but fail with it, I've split it into two files (one with run-pass and one without). If there's a better way I can amend it.

Part of rust-lang#44874

r? ```@wesleywiser```
rust-timer added a commit to rust-lang-ci/rust that referenced this issue Dec 21, 2024
Rollup merge of rust-lang#134509 - adetaylor:niche-deshadowing-tests, r=wesleywiser

Arbitrary self types v2: niche deshadowing test

Arbitrary self types v2 attempts to detect cases where methods in an "outer" type (e.g. a smart pointer) might "shadow" methods in the referent.

There are a couple of cases where the current code makes no attempt to detect such shadowing. Both of these cases only apply if other unstable features are enabled.

Add a test, mostly for illustrative purposes, so we can see the shadowing cases that can occur.

Part of rust-lang#44874
r? ```@wesleywiser```
lnicola pushed a commit to lnicola/rust-analyzer that referenced this issue Dec 23, 2024
…=compiler-errors,wesleywiser

Arbitrary self types v2: main compiler changes

This is the main PR in a series of PRs related to Arbitrary Self Types v2, tracked in #44874. Specifically this is step 7 of the plan [described here](rust-lang/rust#44874 (comment)), for [RFC 3519](rust-lang/rfcs#3519).

Overall this PR:
* Switches from the `Deref` trait to the new `Receiver` trait when the unstable `arbitrary_self_types` feature is enabled (the simple bit)
* Introduces new algorithms to spot "shadowing"; that is, the case where a newly-added method in an outer smart pointer might end up overriding a pre-existing method in the pointee (the complex bit). Most of this bit was explored in [this earlier perf-testing PR](rust-lang/rust#127812 (comment)).
* Lots of tests

This should not break compatibility for:
* Stable users, where it should have no effect
* Users of the existing `arbitrary_self_types` feature (because we implement `Receiver` for `T: Deref`) _unless_ those folks have added methods which may shadow methods in inner types, which we no longer want to allow

Subsequent PRs will add better diagnostics.

It's probably easiest to review this commit-by-commit.

r? `@wesleywiser`
DianQK added a commit to DianQK/rust that referenced this issue Dec 25, 2024
…=wesleywiser

Arbitrary self types v2: unstable doc updates.

Document these two feature flags.

Part of rust-lang#44874 .
rust-timer added a commit to rust-lang-ci/rust that referenced this issue Dec 25, 2024
Rollup merge of rust-lang#134525 - adetaylor:unstable-book-changes, r=wesleywiser

Arbitrary self types v2: unstable doc updates.

Document these two feature flags.

Part of rust-lang#44874 .
@adetaylor
Copy link
Contributor

Another periodic update:

Next steps:

adetaylor added a commit to google/autocxx that referenced this issue Jan 22, 2025
Background:

Rust references have certain rules, most notably that the underlying data
cannot be changed while an immutable reference exists. That's essentially
impossible to promise for any C++ data; C++ may retain references or pointers
to data any modify it at any time. This presents a problem for Rust/C++ interop
tooling. Various solutions or workarounds are possible:

1) All C++ data is represented as zero-sized types.
   This is the approach taken by cxx for opaque types. This sidesteps all of the
   Rust reference rules, since those rules only apply to areas of memory that
   are referred to. This doesn't really work well enough for autocxx since
   we want to be able to keep C++ data on the Rust stack, using all the fancy
   moveit shenanigans, and that means that Rust must know the true size and
   alignment of the type.

2) All C++ data is represented as UnsafeCell<MaybeUninit<T>>.
   This also sidesteps the reference rules. This would be a valid option for
   autocxx.

3) Have a sufficiently simple language boundary that humans can
   reasonably guarantee there are no outstanding references on the C++ side
   which could be used to modify the underlying data.
   This is the approach taken by cxx for cxx::kind::Trivial types. It's
   just about possible to cause UB using one of these types, but you really
   have to work at it. In practice such UB is unlikely.

4) Never allow Rust references to C++ types. Instead use a special
   smart pointer type in Rust, representing a C++ reference.
   This is the direction in this PR.

More detail on this last approach here:
https://medium.com/@adetaylor/are-we-reference-yet-c-references-in-rust-72c1c6c7015a

This facility is already in autocxx, by adopting the safety policy
"unsafe_references_wrapped". However, it hasn't really been battle tested
and has a bunch of deficiencies.

It's been awaiting formal Rust support for "arbitrary self types" so that methods
can be called on such smart pointers. This is now
[fairly close to stabilization](rust-lang/rust#44874 (comment));
this PR is part of the experimentation required to investigate whether that rustc
feature should go ahead and get stabilized.

This PR essentially converts autocxx to only operate in this mode - there should
no longer ever be Rust references to C++ data.

This PR is incomplete:
* There are still 60 failing integration tests. Mostly these relate to subclass
  support, which isn't yet converted.
* `ValueParam` and `RValueParam` need to support taking `CppPin<T>`, and possibly
  `CppRef<T: CopyNew>` etc.
* Because we can't implement `Deref` for `cxx::UniquePtr<T>` to emit a
  `CppRef<T>`, unfortunately `cxx::UniquePtr<T>` can't be used in cases where
  we want to provide a `const T&`. It's necessary to call `.as_cpp_ref()` on the
  `UniquePtr`. This is sufficiently annoying that it might be necessary to
  implement a trait `ReferenceParam` like we have for `ValueParam` and `RValueParam`.
  (Alternatives include upstreaming `CppRef<T>` into cxx, but per reason 4 listed
  above, the complexity probably isn't merited for statically-declared cxx
  interfaces; or separating from cxx entirely.)

This also shows up a [Rustc problem which is fixed here](rust-lang/rust#135179).

Ergonomic findings:
* The problem with `cxx::UniquePtr` as noted above.
* It's nice that `Deref` coercion allows methods to be called on `CppPin` as well
  as `CppRef`.
* To get the same benefit for parameters being passed in by reference, you need
  to pass in `&my_cpp_pin_wrapped_thing` which is weird given that the whole
  point is we're trying to avoid Rust references. Obviously, calling `.as_cpp_ref()`
  works too, so this weirdness can be avoided.
* When creating some C++ data `T`, in Rust, it's annoying to have to decide a-priori
  whether it'll be Rust or C++ accessing the data. If the former, you just create
  a new `T`; if the latter you need to wrap it in `CppPin::new`. This is only
  really a problem when creating a C++ object on which you'll call methods. It
  feels like it'll be OK in practice. Possibly this can be resolved by making
  the method receiver some sort of `impl MethodReceiver<T>` generic; an implementation
  for `T` could be provided which auto-wraps it into a `CppPin` (consuming it at that
  point). This sounds messy though. A bit more thought required, but even if this
  isn't possible it doesn't sound like a really serious ergonomics problem,
  especially if we can use `#[diagnostic::on_unimplemented]` somehow to guide.

Next steps here:
* Stabilize arbitrary self types. This PR has gone far enough to show that
  there are no really serious unexpected issues there.
* Implement `ValueParam` and `RValueParam` as necessary for `CppRef` and
  `CppPin` types.
* Work on those ergonomic issues to the extent possible.
* Make a bold decision about whether autocxx should shift wholesale away from
  `&` to `CppRef<T>`. If so, this will be a significant breaking change.
@adetaylor
Copy link
Contributor

I'm working on a stabilization report here - hopefully will post it tomorrow - meanwhile a draft PR for stabilization is here.

@nikomatsakis
Copy link
Contributor

@adetaylor we have been discussing the idea of adopting a new stabilization template which is a series of questions:

https://hackmd.io/@nikomatsakis/Sy7wJC9Ikx

I haven't gotten around to opening a PR for this, but I request that you give it a try and tell me how it works for you. It is meant to help ensure we catch common mistakes.

@adetaylor
Copy link
Contributor

OK will do - in that case I withdraw my earlier suggestion that I'd post the stabilization report today - it will take a couple more days to get all that stuff together (I agree it makes sense though)

@nikomatsakis
Copy link
Contributor

nikomatsakis commented Jan 23, 2025 via email

@adetaylor
Copy link
Contributor

adetaylor commented Jan 24, 2025

This comment formerly contained a stabilization report, which on request I've moved to #135881.

@compiler-errors
Copy link
Member

compiler-errors commented Jan 24, 2025

@adetaylor: It would be cool if you broke this out into another issue or ideally put the stabilization onto the stabilization PR itself.

Burying into the comment history of a tracking issue seems hard to manage with comments, feedback, concerns, and generally other things here.

@adetaylor
Copy link
Contributor

OK - stabilization report moved to #135881.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
B-RFC-approved Blocker: Approved by a merged RFC but not yet implemented. B-unstable Blocker: Implemented in the nightly compiler and unstable. C-tracking-issue Category: An issue tracking the progress of sth. like the implementation of an RFC F-arbitrary_self_types `#![feature(arbitrary_self_types)]` S-tracking-needs-summary Status: It's hard to tell what's been done and what hasn't! Someone should do some investigation. S-types-deferred Status: Identified as a valid potential future enhancement that is not currently being worked on T-lang Relevant to the language team, which will review and decide on the PR/issue. T-types Relevant to the types team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests