Skip to content

Commit b1e24a1

Browse files
committed
fix(macro): reference mutability inside Option #515
1 parent 6b192e8 commit b1e24a1

File tree

3 files changed

+18
-2
lines changed

3 files changed

+18
-2
lines changed

crates/macros/src/function.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -540,9 +540,11 @@ impl<'a> Args<'a> {
540540
.and_then(|ga| match ga {
541541
GenericArgument::Type(ty) => Some(match ty {
542542
Type::Reference(r) => {
543+
// Only mark as_ref for mutable references
544+
// (Option<&mut T>), not immutable ones (Option<&T>)
545+
as_ref = r.mutability.is_some();
543546
let mut new_ref = r.clone();
544547
new_ref.mutability = None;
545-
as_ref = true;
546548
Type::Reference(new_ref)
547549
}
548550
_ => ty.clone(),

tests/src/integration/array/array.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,3 +79,10 @@
7979

8080
assert(array_key_exists('00', $leading_zeros), '"00" should stay as string key');
8181
assert($leading_zeros['00'] === 'zerozero', 'Value at key "00" should be "zerozero"');
82+
83+
// Test Option<&ZendHashTable> with literal array (issue #515)
84+
// This should work without "could not be passed by reference" error
85+
assert(test_optional_array_ref([1, 2, 3]) === 3, 'Option<&ZendHashTable> should accept literal array');
86+
assert(test_optional_array_ref(null) === -1, 'Option<&ZendHashTable> should accept null');
87+
$arr = ['a', 'b', 'c', 'd'];
88+
assert(test_optional_array_ref($arr) === 4, 'Option<&ZendHashTable> should accept variable array');

tests/src/integration/array/mod.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use ext_php_rs::{
55
ffi::HashTable,
66
php_function,
77
prelude::ModuleBuilder,
8-
types::{ArrayKey, Zval},
8+
types::{ArrayKey, ZendHashTable, Zval},
99
wrap_function,
1010
};
1111

@@ -41,13 +41,20 @@ pub fn test_array_keys() -> Zval {
4141
ht.into_zval(false).unwrap()
4242
}
4343

44+
/// Test that Option<&ZendHashTable> can accept literal arrays (issue #515)
45+
#[php_function]
46+
pub fn test_optional_array_ref(arr: Option<&ZendHashTable>) -> i64 {
47+
arr.map(|ht| ht.len() as i64).unwrap_or(-1)
48+
}
49+
4450
pub fn build_module(builder: ModuleBuilder) -> ModuleBuilder {
4551
builder
4652
.function(wrap_function!(test_array))
4753
.function(wrap_function!(test_array_assoc))
4854
.function(wrap_function!(test_array_assoc_array_keys))
4955
.function(wrap_function!(test_btree_map))
5056
.function(wrap_function!(test_array_keys))
57+
.function(wrap_function!(test_optional_array_ref))
5158
}
5259

5360
#[cfg(test)]

0 commit comments

Comments
 (0)