hhvm icon indicating copy to clipboard operation
hhvm copied to clipboard

[ Feature Request ] Top-level `use` statements should be permitted before namespace declarations/blocks

Open lexidor opened this issue 6 years ago • 6 comments
trafficstars

HHVM Version

HipHop VM 4.8.0 (rel)
Compiler: 1559583155_055573146
Repo schema: bbe84ac83be4cac392df68fc2c6cc8b7c6516bfd
hackc-e178a2330ba29a6fff3a77b4d56e11cc33959179-4.8.0

Operating System and Version

Ubuntu 18.04 (desktop edition)

Standalone code, or other way to reproduce the problem

use namespace HH\Lib\{C, Vec};

namespace AnyNamespace {
	function useless(): void {
		C\count(Vec\filter(vec[]));
	}
}

Actual result

Parsing[1002] No code may exist outside of namespace {}
   --> src/namespace.hack
  3 | namespace AnyNamespace {
    | ^^^^^^^^^^^^^^^^^^^^^^^^

Parsing[1002] Namespace declaration statement has to be the very first statement in the script
   --> src/namespace.hack
  3 | namespace AnyNamespace {
    | ^^^^^^^^^^^^^^^^^^^^^^^^

Expected result

There is no reason to restrict the usage of namespace groupings like this, since the code is functionally equivalent to:

use namespace HH\Lib\C;
use namespace HH\Lib\Vec;

namespace AnyNamespace {
	function useless(): void {
		C\count(Vec\filter(vec[]));
	}
}

lexidor avatar Jun 09 '19 19:06 lexidor

Does the last example in the description work? As I understand it, all statements must be inside the namespace block (if there is one).

kmeht avatar Jun 09 '19 21:06 kmeht

The last example works. Both in the typechecker as in the runtime.

lexidor avatar Jun 10 '19 02:06 lexidor

<?hh // strict

use namespace HH\Lib\Vec;

namespace ForAnExample {
    <<__EntryPoint>>
    async function for_an_example(): Awaitable<void> {
        require_once __DIR__.'/../vendor/hh_autoload.php';
        \var_dump(Vec\filter(vec[]));
    }
}

Results in:

vec(0) {
}

lexidor avatar Jun 10 '19 02:06 lexidor

<?hh // strict

use namespace HH\Lib\{Vec, C};

namespace ForAnExample {
    <<__EntryPoint>>
    async function for_an_example(): Awaitable<void> {
        require_once __DIR__.'/../vendor/hh_autoload.php';
        \var_dump(Vec\filter(vec[]));
    }
}

Results in:

Fatal error: Uncaught Error: No code may exist outside of namespace {} in /path/to/file.php:11
Stack trace:
#0 {main}

lexidor avatar Jun 10 '19 02:06 lexidor

I should not be put in charge of language design, but banning these constructions would make it harder to define code in two namespaces while using shared use namespace HH\Lib\xxx. I suggest to have the restrictions lifted. (Else we'll just wrap the entire file in a big namespace {/*CODE*/}. That circumvents the top level statement check too.

lexidor avatar Jun 10 '19 02:06 lexidor

@kmeht Does it seem likely that this grammar rule is updated one way or another? Either reject use outside of a namespace block or allow grouped ones too?

lexidor avatar Sep 16 '19 17:09 lexidor