You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Since in #327 (and maybe #328) I run into issues with registration order, I think that Rust compilation order, which ext-php-rs relied has been broken at least under some circumstances, which screws up at the very least rust analyzer.
I started investigating the cause of this error. ext-php-rs has a static STATE that things get registered in during macro expansion. This has lines like:
if state.built_module{bail!("The `#[php_module]` macro must be called last to ensure functions and classes are registered.");}if state.startup_function.is_some(){bail!("The `#[php_startup]` macro must be called after all the classes have been defined.");}
which are causing the problem.
Not checking
As a relatively simple hack we could just disable these lines. That would fix the macro errors I think, but then you'd get absolutely no warning that your functions and classes aren't actually being registered. That's risky as we are already getting errors about the order of registration, and the order of macro expansion is not guaranteed.
Explicit mode
I started investigating what it would be required to have explicit registration. I envision a mode where you write
#[php_class(explicit)
and you're then required to register it explicitly in the module builder.
What does explicit do?
With an explicit flag, we could instead generate static annotations for the various macros (such as a class description, or function description) that only later is explicitly referred to during registration.
I'll note that php_class_explicit is a macro so that it looks for associated registrations that are generated by the php_class. These registrations are stored by the macro in a module that's generated associated with Foo. Unfortunately we can't call this module Foo as we need access to the original Foo in non-macro code, so some magic will need to remain (you can't import Foo and register it in another module, you're better off implementing a new get_module in that module and then invoke it from the original one.
Implementation challenges
Unfortunately the current system relies heavily on the ability to register things during compile time. It builds extensive structs during compile time (such as Class) which are then registered. Ideally in the explicit system we don't want such a global object at all, as in that case we'd still be dependent on import order which can break - php_module needs to be called at the very last for it to work, and we can't guarantee that.
To be really explicit, each registration has to be independent, and that means generating quite a bit of stuff in the macro. But luckily it looks like this is already happening anyway in order to support build_classes. So for each class for instance we'd want to generate a separate function that builds the class. The current logic also calls builder.build() which is NOT what we want in explicit mode, as it registers the class with PHP too. We only want to invoke build once the explicit get_module has collected all required information.
So this is going to require quite a bit of refactoring to make it work...
PS
Some of this may be difficult to follow as I'm thinking as I'm writing it. If you're interested in this problem, let me know!
The text was updated successfully, but these errors were encountered:
I would like to have a more in depth look at how macros can be improved first, before tackling this one, as that might have implications on how to implement this (or even make this obsolete).
From what I have seen a bigger refactoring of how the macros work might be in order. Will tag you once I've written a proposal.
Since in #327 (and maybe #328) I run into issues with registration order, I think that Rust compilation order, which ext-php-rs relied has been broken at least under some circumstances, which screws up at the very least rust analyzer.
I started investigating the cause of this error.
ext-php-rs
has a static STATE that things get registered in during macro expansion. This has lines like:which are causing the problem.
Not checking
As a relatively simple hack we could just disable these lines. That would fix the macro errors I think, but then you'd get absolutely no warning that your functions and classes aren't actually being registered. That's risky as we are already getting errors about the order of registration, and the order of macro expansion is not guaranteed.
Explicit mode
I started investigating what it would be required to have explicit registration. I envision a mode where you write
#[php_class(explicit)
and you're then required to register it explicitly in the module builder.
What does explicit do?
With an
explicit
flag, we could instead generate static annotations for the various macros (such as a class description, or function description) that only later is explicitly referred to during registration.Then you'd register things explicitly:
I'll note that
php_class_explicit
is a macro so that it looks for associated registrations that are generated by thephp_class
. These registrations are stored by the macro in a module that's generated associated withFoo
. Unfortunately we can't call this moduleFoo
as we need access to the originalFoo
in non-macro code, so some magic will need to remain (you can't import Foo and register it in another module, you're better off implementing a newget_module
in that module and then invoke it from the original one.Implementation challenges
Unfortunately the current system relies heavily on the ability to register things during compile time. It builds extensive structs during compile time (such as
Class
) which are then registered. Ideally in the explicit system we don't want such a global object at all, as in that case we'd still be dependent on import order which can break -php_module
needs to be called at the very last for it to work, and we can't guarantee that.To be really explicit, each registration has to be independent, and that means generating quite a bit of stuff in the macro. But luckily it looks like this is already happening anyway in order to support
build_classes
. So for each class for instance we'd want to generate a separate function that builds the class. The current logic also callsbuilder.build()
which is NOT what we want in explicit mode, as it registers the class with PHP too. We only want to invoke build once the explicitget_module
has collected all required information.So this is going to require quite a bit of refactoring to make it work...
PS
Some of this may be difficult to follow as I'm thinking as I'm writing it. If you're interested in this problem, let me know!
The text was updated successfully, but these errors were encountered: