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

Manual block encodings #636

Open
wants to merge 8 commits into
base: master
Choose a base branch
from

Conversation

PaulDance
Copy link
Contributor

@PaulDance PaulDance commented Jul 5, 2024

Hey @madsmtm!

This is an attempt to contribute to #442, by adding the ability to manually provide a block encoding to its constructor so that it sets BLOCK_HAS_SIGNATURE and saves the string properly.

Included:

  • New StackBlock::with_encoding.
  • New RcBlock::with_encoding.
  • block2::traits::ManualBlockEncoding is the smuggling trait.
  • String check on cfg(debug_assertions): a bit too strict for now, but can be relaxed later on by implementing a dedicated parser and equivalence checking.
  • Updated and new tests.

Cheers,
Paul.

@madsmtm
Copy link
Owner

madsmtm commented Jul 14, 2024

dangling pointers

Right, &Self::DESCRIPTOR_WITH_CLONE works because it is promoted to a static, but that can't happen if we construct the descriptor on the stack. I've documented this somewhat in 893d044.

I think my preferred solution (for now) would be something like the following instead (similar to your proposal in #442 (comment), just with an extra trait):

unsafe trait BlockEncodingHelper { // Bikeshed name
    type Arguments: EncodingArguments;
    type Return: EncodingReturn;
    const ENCODING_CSTR: &'static CStr;
}

impl Block {
    pub fn with_encoding<'f, A, R, Closure, Helper>(
        _helper: Helper,
        closure: Closure,
    ) -> Self
    where
        Helper: BlockEncodingHelper<Arguments = A, Return = R>,
        // ...
    { ... }
}

// Usage
struct Helper;

impl BlockEncodingHelper for Helper {
    type Arguments = (i32, Bool);
    type Return = u8;
    const ENCODING_CSTR: &'static CStr = c"whatever_the_encoding_is_I_have_not_checked_it";
}

let block = RcBlock::with_encoding(Helper, |arg1, arg2| {
    if arg2.as_bool() {
        arg1 as u8
    } else {
        0
    }
});

@PaulDance
Copy link
Contributor Author

Right, &Self::DESCRIPTOR_WITH_CLONE works because it is promoted to a static

Ah yes, I was suspecting something of the sort was happening behind the scenes, but did not know the exact underlying mechanism. Thanks for the link.

I think my preferred solution (for now) would be something like the following instead

That seems like it could work, yes thanks. I'll try it soon and see if the promotion works in this case too.

@PaulDance PaulDance force-pushed the manual-block-encodings branch 2 times, most recently from 7bc92d7 to f796013 Compare July 17, 2024 10:29
Signed-off-by: Paul Mabileau <paul.mabileau@harfanglab.fr>
Copy link
Owner

@madsmtm madsmtm left a comment

Choose a reason for hiding this comment

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

I haven't reviewed all of it yet (use GitHub's UI to request a review when you want me to do so), only saw that you're bumping MSRV, please don't do that.

I think all the examples and tests can use c"string" without affecting MSRV, but in the places where the actual code is, you'll have to use unsafe { CStr::from_bytes_with_nul_unchecked(b"string\0") } instead.

crates/block2/Cargo.toml Outdated Show resolved Hide resolved
@PaulDance
Copy link
Contributor Author

I haven't reviewed all of it yet (use GitHub's UI to request a review when you want me to do so)

Yes, sorry for the notifications, I just wanted to make things work and then check that I haven't missed anything, such as adding new tests, hence why I left is as a draft.

saw that you're bumping MSRV, please don't do that

That was also part of the things I wanted to do before formally asking for a review, sorry. 😅

CStr was stabilized in 1.64 and the current MSRV is 1.60, so in any case it has to be bumped, right? Regarding why 1.79 specifically, which I understand constitutes a bit of an aggressive jump, it is for inline consts that I used to guarantee the const fn calls I made were indeed promoted, especially considering things like rust-lang/rust#121557. If you see any other way to do this without loosing these guarantees, then yes, I'll lower it as much as possible.

@madsmtm
Copy link
Owner

madsmtm commented Jul 17, 2024

CStr was stabilized in 1.64

Preeetty sure that was only CStr in core, the docs are just bad at visualizing this. CStr has been available since basically forever.

guarantee the const fn calls I made were indeed promoted

Perhaps we can just avoid using the const fns here? From my reading of the code, you seem to be using it mostly to have the definition of e.g. BlockDescriptorCopyDisposeSignature next to BlockDescriptorCopyDispose (which is commendable, but also perhaps a bit unnecessary here).

If not, then there are ways to do the equivalent of inline const with traits and associated constants.

@PaulDance
Copy link
Contributor Author

Preeetty sure that was only rust-lang/rust#98314, the docs are just bad at visualizing this. CStr has been available since basically forever.

Woops, sorry. That seems right, yes. Looking at the methods I use, I should be able to avoid any bump here, hopefully.

Perhaps we can just avoid using the const fns here?

Probably, yes. I just wanted to avoid the "let's hope promotion works similarly in previous and future compiler versions" kind of stance, although it should be acceptable 🤞

If not, then there are ways to do the equivalent of inline const with traits and associated constants.

I'll try the above first and then this if it fails somehow. Thanks for the suggestion.

@PaulDance
Copy link
Contributor Author

PaulDance commented Jul 18, 2024

In the end, the MSRV bump was indeed not necessary:

  • the C string literals and too recent CStr methods were able to be circumvented;
  • static promotion was successfully made functional without const fns and inline const expressions and with the suggested trait smuggling, as simply inlining the value made it fail to promote in practice;

Last thing I need to do before declaring this ready to review: try to add the cfg(debug_assertions)-gated encoding string safety checks.

@PaulDance PaulDance force-pushed the manual-block-encodings branch 2 times, most recently from 9166751 to 91a730f Compare July 19, 2024 14:22
Signed-off-by: Paul Mabileau <paul.mabileau@harfanglab.fr>
Signed-off-by: Paul Mabileau <paul.mabileau@harfanglab.fr>
@PaulDance PaulDance force-pushed the manual-block-encodings branch 3 times, most recently from 0d190d3 to 60689ff Compare July 19, 2024 15:26
…onstructors

Signed-off-by: Paul Mabileau <paul.mabileau@harfanglab.fr>
 * `StackBlock`'s `Clone` constraint checks: order switch it seems.
 * `OptionEncode` compile-time checks: small line number shift.

Signed-off-by: Paul Mabileau <paul.mabileau@harfanglab.fr>
Small movements it seems.

Signed-off-by: Paul Mabileau <paul.mabileau@harfanglab.fr>
Signed-off-by: Paul Mabileau <paul.mabileau@harfanglab.fr>
@PaulDance PaulDance force-pushed the manual-block-encodings branch 6 times, most recently from 5513ae9 to ae5820d Compare July 19, 2024 16:38
Signed-off-by: Paul Mabileau <paul.mabileau@harfanglab.fr>
@PaulDance PaulDance marked this pull request as ready for review July 19, 2024 16:57
@PaulDance PaulDance requested a review from madsmtm July 19, 2024 16:57
@PaulDance
Copy link
Contributor Author

Alright @madsmtm, this should now be ready for a proper first review cycle! Sorry for the many CI runs, though, I just struggled endlessly with minor details.

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.

None yet

2 participants