Skip to content

Make blocks with encoding easier to use #651

Open

Description

@madsmtm

#636 added [Rc|Stack]Block::with_encoding, but they're pretty cumbersome to use because you have to create a helper structure, and implement ManualBlockEncoding with the correct encoding.

What's the solution when something is cumbersome? Make it automatic!

An idea would be to write a script that uses libclang, goes through all Apple's headers, on a few different targets, and generates the correct ManualBlockEncoding for the corresponding fn(A) -> Rs.

This would allow the user to write RcBlock::with_encoding<fn(i32) -> i32, _, _>(|x| x * x) in the vast majority of cases.

CC @PaulDance

Activity

  1. madsmtm commented on Sep 8, 2025

    @madsmtm
    OwnerAuthor

    I recall having a quick look at the amount of block signatures that Apple uses a month back, and it was unfortunately several hundred, which is probably too large a compile-time hit :/.

    So we'll probably have to wait for generic const expressions (see 050b502 for a test with that).

  2. madsmtm commented on Mar 4, 2026

    @madsmtm
    OwnerAuthor

    An idea from #70: Since we can generate encoding strings in const, just not generically, maybe add something like:

    // block2
    pub fn block_encoding_str_len(args: &[Encoding], ret: &Encoding) -> usize { ... }
    pub fn block_encoding_str_array<const LEN: usize>(args: &[Encoding], ret: &Encoding) -> [LEN; u8] { ... }
    
    // Usage
    struct MyBlockEncoding;
    // SAFETY: The encoding is correct.
    unsafe impl ManualBlockEncoding for MyBlockEncoding {
        type Arguments = (*mut NSError,);
        type Return = i32;
        const ENCODING_CSTR: &'static CStr = {
            const LEN: usize = block_encoding_str_len(<(*mut NSError,)>::ENCODINGS, i32::ENCODING_RETURN);
            let arr = block_encoding_str_array::<LEN>(<(*mut NSError,)>::ENCODINGS, i32::ENCODING_RETURN);
            CStr::from_bytes_with_nul(&arr).unwrap()
        };
    }

    And maybe wrap it in a macro like:

    block2::manual_encoding!(fn MyBlockEncoding(error: *mut NSError) -> i32);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-block2Affects the `block2` crateenhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions