Tested with AS rev 1176 (and can't see anything about fixing these in the commitlog).
1. The following gives "Can't return value when return type is 'void'." upon compilation:
shared int f()
{
return 0;
}
2. imported functions are always considered non-shared and thus are unusable in any shared code. Perhaps imported functions should be always treated as shared, or maybe it could be done explicitly:
import shared int f() from "module";
Imported functions are not 'shared'. This is because the imported functions are dynamically linked individually per module. Imported functions will also access the global variables in the originating module. To be 'shared' the function (or other entity) cannot have any module specific behaviour.
It is possible to import a function that is shared by another module, but then you hide the fact that the function is shared.
What would be wrong with checking if an imported function used by a shared code is shared upon bind time, and giving a bind error if it isn't?
// module mod1
shared void f1() { }
void f2() { }
// module mod2
import void f1() from "mod1";
import void f2() from "mod1";
shared void g()
{
f1();
f2(); // bind error on this one when BindAllImportedFunctions()
}
The actual bind id is still module specific, so the function g() cannot be compiled in a module independent way.
What exactly are you trying to accomplish? Perhaps there is an easier way. If the function already is shared, then there is not really any need to import it. Simply declare it again as shared, and it will be the same function.
I have a few large modules that serve as a general API for every scripted ingame feature, coupled with a header script for each one of them that is nothing more than a wall of imports (plus macros and interfaces used). Then, I have some utility classes inlined in several modules (I'd like them to be shared for that reason) that use those headers. While I could simply put the function bodies in said headers to make it work, it is not an option: our headers are readily available to a larger group of people who do not have the access to the modules themselves, for security reasons (at best they receive them in a binary form; but generally they can only send new scripts to an isolated testing environment and run stuff remotely). Of a lesser importance is that the code would be somewhat uglier.
I think in this case you can take advantage of an undocumented feature: A shared function is not re-compiled if it finds a pre-existing function from another module. The same goes for classes, interfaces, and enums.
Using this you can can declare the shared function with an empty body in the header that you distribute to your clients. The main module will provide the true implementation.
shared int f() {}
shared class c {}
shared interface i {}
shared enum e {}
You just need to make sure the large module that has the real function implementation is always compiled before any other modules that will only have the empty function, class, interface, or enum.