xp-framework/compiler

Compiler error: Call to a member function children() on string

thekid opened this issue · 2 comments

Relevant part of the stacktrace with PHP < 7.4

  Caused by Exception lang.Error (Call to a member function children() on string)
    at <native>::Error(0, (0x2e)'Call to a member function children() on string') [line 19 of CodeGen.class.php]
    at lang.ast.CodeGen::search() [line 17 of CodeGen.class.php] Trying to get property 'kind' of non-object
    at lang.ast.CodeGen::search((0x7)'literal', (0x8)'variable') [line 20 of CodeGen.class.php]
    at lang.ast.CodeGen::search(lang.ast.nodes.MatchCondition{}, (0x8)'variable') [line 20 of CodeGen.class.php]
    at lang.ast.CodeGen::search(lang.ast.nodes.MatchExpression{}, (0x8)'variable') [line 20 of CodeGen.class.php]
    at lang.ast.CodeGen::search(lang.ast.nodes.LambdaExpression{}, (0x8)'variable') [line 59 of PHP.class.php]
    at lang.ast.emit.PHP::enclose(lang.ast.Result{}, lang.ast.nodes.LambdaExpression{}, lang.ast.nodes.Signature{}, function()) [line 21 of RewriteLambdaExpressions.class.php]
    at lang.ast.emit.PHP72::emitLambda(lang.ast.Result{}, lang.ast.nodes.LambdaExpression{}) [line 125 of Emitter.class.php]

Solution for the moment:

-    $lookup= fn($prefix) => match ($prefix) {
-      '_'     => '',
-      default => $this->namespaces[$prefix] ?? $this->base
-    };
+    $lookup= fn($prefix) => '_' === $prefix ? '' : $this->namespaces[$prefix] ?? $this->base;

This test verifies the bug exists:

  #[Test]
  public function match_inside_fn() {
    $r= $this->run('class <T> {
      public function run() {
        return fn($arg) => match {
          $arg >= 10 => "10+ items",
          $arg === 1 => "one item",
          $arg === 0 => "no items",
          default    => $arg." items",
        };
      }
    }');

    Assert::equals('10+ items', $r(10));
  }