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

Add support for arbitrary arrays #1128

Merged
merged 5 commits into from
May 1, 2021
Merged

Add support for arbitrary arrays #1128

merged 5 commits into from
May 1, 2021

Conversation

c410-f3r
Copy link
Contributor

Extends my previous work on #778 and an additional PR will soon be provided to remove the Default bound restriction.

If rust-lang/rust#75644 is going to be accepted, then the auxiliary functions won't be necessary in the near future.

@kngwyu
Copy link
Member

kngwyu commented Aug 31, 2020

Thank you, but is there any strong reason we should have this nightly feature?
I think we can wait for stabilization.

@davidhewitt
Copy link
Member

Agreed in that I was hoping the goal was to remove the nightly feature. Maybe instead of providing this in the pyo3 core, we can extend the new FromPyObject derive to be able to plug in custom converters similar to #[serde(deserialize_with = ...)], and then the array support could be provided in a separate crate?

@birkenfeld
Copy link
Member

TBH I'd rather this to be kept behind a feature flag for longer, than get merged without the second that const-generics are stabilized (#1076 calling).

@davidhewitt
Copy link
Member

Agreed whatever we do we should give time for MSRV support to propagate.

@c410-f3r
Copy link
Contributor Author

c410-f3r commented Sep 1, 2020

I did include it within the nightly feature because... you know... it is currently only available in the nightly version of Rustc.

Constant generics is now behind its own opt-in flag and all Default and Copy bounds were removed

src/types/sequence.rs Outdated Show resolved Hide resolved
@kngwyu
Copy link
Member

kngwyu commented Sep 1, 2020

I did include it within the nightly feature because... you know... it is currently only available in the nightly version of Rustc.

What I meant as feature is what this PR does and not the feature flag itself. My intention was keeping the code base reasonably small.

Anyway, let's consider merging after the upstream PR is merged.

@kngwyu
Copy link
Member

kngwyu commented Sep 1, 2020

Ah, and I realized that now we don't have any tests for nightly feature.

@davidhewitt
Copy link
Member

Ah, and I realized that now we don't have any tests for nightly feature.

As the nightly feature is just adding optimizations, there's not much testing to be added other than an extra CI job which runs with the flag enabled.

I'd prefer to move away from the pyo3 core crate having any CI which requires nightly, as it consumes contributor time (e.g. PRs spuriously failing because something changed in nightly). Hence my question above whether we can make this easy to integrate via a separate crate for now.

@davidhewitt
Copy link
Member

I have been thinking further on this topic, and I wanted to propose that we do support this PR, behind a new feature. I think it's beneficial to the Rust ecosystem that we support this because it enables more users to experiment with const generics. This can help the feature to eventually stabilize and also benefits immediately our users on nightly Rust.

(Even serde has an unstable feature for things like this: https://github.com/serde-rs/serde/blob/e3d871ff7bf10dadf10bdc234a55692228358d0e/serde/Cargo.toml#L45)

I'd prefer to keep away from having a single nightly feature, because I want users to know what they're opting in to and because I want to name it clearly that it's not guaranteed to be supported forever.

So I propose to move forward on this PR with a new feature named unstable-const-generics.

@c410-f3r
Copy link
Contributor Author

@davidhewitt Maybe wait for the 1.50 release?

rust-lang/rust#79135

@c410-f3r
Copy link
Contributor Author

The time has come.
Are you guys still using the latest stable compiler on master? Maybe I should put back the cons-generics feature flag.

@davidhewitt
Copy link
Member

We support all the way back to Rust 1.41, so this will need to go behind a const-generics feature flag, yes.

@davidhewitt
Copy link
Member

An alternative to a user-facing feature flag is we could detect the compiler version in the build script, and then conditionally enable const generics based on that.

@c410-f3r
Copy link
Contributor Author

c410-f3r commented Mar 25, 2021

We support all the way back to Rust 1.41, so this will need to go behind a const-generics feature flag, yes.

I miss the good ol' days when nightly was the only thing available for this project

An alternative to a user-facing feature flag is we could detect the compiler version in the build script, and then conditionally enable const generics based on that.

Sure, this is a good approach. I will update everything accordingly. Thanks!

@davidhewitt
Copy link
Member

👍 you might be interested in anyhow's build.rs which enables backtrace support in this fashion. We might be able to follow a similar pattern here.

https://github.com/dtolnay/anyhow/blob/master/build.rs

@c410-f3r c410-f3r changed the title Support for arbitrary arrays Add support for arbitrary arrays Mar 25, 2021
@c410-f3r c410-f3r force-pushed the array branch 4 times, most recently from 2afaa93 to 5370406 Compare March 25, 2021 19:07
@c410-f3r
Copy link
Contributor Author

Clippy failure is not related to this PR

Copy link
Member

@davidhewitt davidhewitt left a comment

Choose a reason for hiding this comment

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

Thanks very much for the continued refinements! This is looking great.

Afraid I have another round of comments; I think we're really close now, very excited to see this land! 😅

As well as the comments below, I have two additional points:

  • When I suggested moving code into conversions/array.rs, I meant all of the existing array_impls! macros and tests too. If it's all together in one place it's much easier for reviewers to audit what's tested and also maintain in the future once we don't need to support older rustc < 1.51.

  • This still needs a CHANGELOG entry. I propose the following:

    ### Added
    - Add conversion for `[T; N]` for all `N` on Rust 1.51 and up. [#1128](https://github.com/PyO3/pyo3/pull/1128)
    

    Happy for you to choose alternative wording if you think there's a better phrase out there.

src/conversions/array.rs Outdated Show resolved Hide resolved
src/conversions/array.rs Outdated Show resolved Hide resolved
src/conversions/mod.rs Outdated Show resolved Hide resolved
src/types/sequence.rs Outdated Show resolved Hide resolved
@c410-f3r c410-f3r force-pushed the array branch 3 times, most recently from 926f70a to 8f47a76 Compare March 31, 2021 12:11
Copy link
Member

@kngwyu kngwyu left a comment

Choose a reason for hiding this comment

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

Thank you for your continuous works, happy to see this works actually! 🎉

build.rs Outdated Show resolved Hide resolved
src/conversions/array.rs Outdated Show resolved Hide resolved
src/conversions/array.rs Outdated Show resolved Hide resolved
Comment on lines 143 to 163
let initialized_part = core::ptr::slice_from_raw_parts_mut(self.dst, *self.initialized);
unsafe {
core::ptr::drop_in_place(initialized_part);
}
Copy link
Member

Choose a reason for hiding this comment

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

Why do we need to drop the initialized slice?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Guard drops the initialized part when the closure panics to prevent leaks

Copy link
Member

Choose a reason for hiding this comment

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

Ah, OK, I'm sorry but I was only thinking of the situation where T is a number or so (then dropping the slice does not mean so much...).
How about using [MaybeUninit<T>; N] instead?
Then, for me, it is clearer that each element should be dropped.
Some examples (https://doc.rust-lang.org/std/mem/union.MaybeUninit.html#initializing-an-array-element-by-element and https://doc.rust-lang.org/src/core/mem/maybe_uninit.rs.html#1042) use this style.
Also, please consider moving ArrayGuard definition in the try_create_array, since it is not used in other places.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This data structure was used by previous releases of the nightly compiler and is battle tested by many people around the globe. Please consider avoid changing its original formulation.

Copy link
Member

Choose a reason for hiding this comment

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

@kngwyu note that eventually an API for this might be added to std: rust-lang/rust#75644

Personally I'm happy as long as we're sure the implementation we use is sound.

@c410-f3r c410-f3r force-pushed the array branch 2 times, most recently from eb0720e to 3ba4a05 Compare March 31, 2021 16:44
Copy link
Member

@davidhewitt davidhewitt left a comment

Choose a reason for hiding this comment

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

Whew, this PR is turning out to be quite fiddly! Thank you for all the effort you've put into this.

I'm apologetic to say I've got another round of comments. In particular I have a concern that we might have some UB inside the try_create_array function.

src/conversions/array.rs Outdated Show resolved Hide resolved
src/conversions/array.rs Outdated Show resolved Hide resolved
src/conversions/array.rs Outdated Show resolved Hide resolved
src/buffer.rs Outdated Show resolved Hide resolved
src/utils.rs Outdated Show resolved Hide resolved
src/conversions/array.rs Outdated Show resolved Hide resolved
@davidhewitt davidhewitt added this to the 0.14 milestone Apr 13, 2021
@davidhewitt davidhewitt mentioned this pull request Apr 19, 2021
7 tasks
@davidhewitt
Copy link
Member

@c410-f3r thanks very much for all the work you've done getting this PR through to this point.

I'm doing some tidying up of pending items ahead of the 0.14 release so I'm shortly going to rebase this PR and push a commit to finish it off so that we can include it in the upcoming release. Hope that's ok.

@davidhewitt davidhewitt force-pushed the array branch 2 times, most recently from 1de9d37 to 7814c2a Compare April 24, 2021 07:46
@c410-f3r
Copy link
Contributor Author

Hey @davidhewitt Thanks for finishing this PR!

@davidhewitt davidhewitt requested a review from kngwyu April 24, 2021 14:05
Copy link
Member

@kngwyu kngwyu left a comment

Choose a reason for hiding this comment

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

Thanks! I have some minor requests for tests

src/conversions/array.rs Outdated Show resolved Hide resolved
src/conversions/array.rs Outdated Show resolved Hide resolved
@davidhewitt davidhewitt merged commit 3ee84a3 into PyO3:main May 1, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants