Skip to content

array-reference lowering: argument position (as_slice / address-of) disagrees with parameter position (std::array&) #44

Description

@shuaimu

Found by the srpc whole-crate transpile (mako crates/srpc), after #41/#42/#43 — the last blocker in the srpc.wire chain.

Repro (cross-module; same-module never materializes it because the callers there are tests):

// varint.rs
pub fn load32(buf: &[u8; 9]) -> i32 { buf[0] as i32 }
pub fn dump32(val: i32, buf: &mut [u8; 9]) -> usize { buf[0] = val as u8; 1 }

// serde.rs
use super::varint;
pub fn ser(v: i32) -> usize {
    let mut b = [0u8; 9];
    let n = varint::dump32(v, &mut b);
    let _ = varint::load32(&b);
    n
}

Parameter position lowers &[u8; 9] / &mut [u8; 9] as const std::array<uint8_t, 9>& / std::array<uint8_t, 9>&. Argument position lowers &b as rusty::as_slice(b) (a std::span<const u8>) and &mut b as &b (a raw pointer):

error: non-const lvalue reference to 'std::array<uint8_t, 9>' cannot bind to a temporary of type 'ArrayRepeatResult<unsigned char>*'
error: no viable conversion from 'std::span<const unsigned char>' to 'const std::array<uint8_t, 9>'

The two sides assume different models (array-ref vs slice-coercion). Options that keep the no-type-inference design: (a) argument-position &/&mut on an array-typed local emits the bare lvalue (binds either param model); (b) uniformly lower array-ref params as fixed-extent spans; (c) use the crate-mode collected signatures to pick per-callee. (a) looks smallest and always safe: a bare lvalue binds std::array& exactly, and where the callee really takes a span the existing implicit array→span conversion covers it.

Concrete failing corpus: srpc.wire.serde.cppm V32/V64 serialize/deserialize (varint::dump32(this->_0, &b) / varint::load32(rusty::as_slice(b))).

Activity

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

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions