Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion crates/macros/src/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -540,9 +540,11 @@ impl<'a> Args<'a> {
.and_then(|ga| match ga {
GenericArgument::Type(ty) => Some(match ty {
Type::Reference(r) => {
// Only mark as_ref for mutable references
// (Option<&mut T>), not immutable ones (Option<&T>)
as_ref = r.mutability.is_some();
let mut new_ref = r.clone();
new_ref.mutability = None;
as_ref = true;
Type::Reference(new_ref)
}
_ => ty.clone(),
Expand Down
7 changes: 7 additions & 0 deletions tests/src/integration/array/array.php
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,10 @@

assert(array_key_exists('00', $leading_zeros), '"00" should stay as string key');
assert($leading_zeros['00'] === 'zerozero', 'Value at key "00" should be "zerozero"');

// Test Option<&ZendHashTable> with literal array (issue #515)
// This should work without "could not be passed by reference" error
assert(test_optional_array_ref([1, 2, 3]) === 3, 'Option<&ZendHashTable> should accept literal array');
assert(test_optional_array_ref(null) === -1, 'Option<&ZendHashTable> should accept null');
$arr = ['a', 'b', 'c', 'd'];
assert(test_optional_array_ref($arr) === 4, 'Option<&ZendHashTable> should accept variable array');
9 changes: 8 additions & 1 deletion tests/src/integration/array/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use ext_php_rs::{
ffi::HashTable,
php_function,
prelude::ModuleBuilder,
types::{ArrayKey, Zval},
types::{ArrayKey, ZendHashTable, Zval},
wrap_function,
};

Expand Down Expand Up @@ -41,13 +41,20 @@ pub fn test_array_keys() -> Zval {
ht.into_zval(false).unwrap()
}

/// Test that `Option<&ZendHashTable>` can accept literal arrays (issue #515)
#[php_function]
pub fn test_optional_array_ref(arr: Option<&ZendHashTable>) -> i64 {
arr.map_or(-1, |ht| i64::try_from(ht.len()).unwrap_or(i64::MAX))
}

pub fn build_module(builder: ModuleBuilder) -> ModuleBuilder {
builder
.function(wrap_function!(test_array))
.function(wrap_function!(test_array_assoc))
.function(wrap_function!(test_array_assoc_array_keys))
.function(wrap_function!(test_btree_map))
.function(wrap_function!(test_array_keys))
.function(wrap_function!(test_optional_array_ref))
}

#[cfg(test)]
Expand Down
Loading