diff --git a/guide/src/macros/classes.md b/guide/src/macros/classes.md index 3a423d1fad..ad62294032 100644 --- a/guide/src/macros/classes.md +++ b/guide/src/macros/classes.md @@ -32,6 +32,34 @@ You can rename the property with options: - `rename` - Allows you to rename the property, e.g. `#[prop(rename = "new_name")]` +## Restrictions + +### No lifetime parameters + +Rust lifetimes are used by the Rust compiler to reason about a program's memory safety. +They are a compile-time only concept; +there is no way to access Rust lifetimes at runtime from a dynamic language like PHP. + +As soon as Rust data is exposed to PHP, +there is no guarantee which the Rust compiler can make on how long the data will live. +PHP is a reference-counted language and those references can be held +for an arbitrarily long time, which is untraceable by the Rust compiler. +The only possible way to express this correctly is to require that any `#[php_class]` +does not borrow data for any lifetime shorter than the `'static` lifetime, +i.e. the `#[php_class]` cannot have any lifetime parameters. + +When you need to share ownership of data between PHP and Rust, +instead of using borrowed references with lifetimes, consider using +reference-counted smart pointers such as [Arc](https://doc.rust-lang.org/std/sync/struct.Arc.html). + +### No generic parameters + +A Rust struct `Foo` with a generic parameter `T` generates new compiled implementations +each time it is used with a different concrete type for `T`. +These new implementations are generated by the compiler at each usage site. +This is incompatible with wrapping `Foo` in PHP, +where there needs to be a single compiled implementation of `Foo` which is integrated with the PHP interpreter. + ## Example This example creates a PHP class `Human`, adding a PHP property `address`.