1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 00:02:20 +01:00

Zend: Add tests for relative types (#17764)

This commit is contained in:
Gina Peter Banyard
2025-02-11 15:18:04 +00:00
committed by GitHub
parent 1ad7743133
commit 8ebf986587
11 changed files with 169 additions and 0 deletions

View File

@@ -0,0 +1,10 @@
--TEST--
Cannot use parent type outside a class/trait: global function
--FILE--
<?php
function foo($x): parent {};
?>
--EXPECTF--
Fatal error: Cannot use "parent" when no class scope is active in %s on line %d

View File

@@ -0,0 +1,12 @@
--TEST--
Cannot use parent type outside a class/trait: interface
--FILE--
<?php
interface T {
function foo($x): parent;
}
?>
--EXPECTF--
Fatal error: Cannot use "parent" when current class scope has no parent in %s on line %d

View File

@@ -0,0 +1,10 @@
--TEST--
Cannot use self type outside a class/trait: global function
--FILE--
<?php
function foo($x): self {};
?>
--EXPECTF--
Fatal error: Cannot use "self" when no class scope is active in %s on line %d

View File

@@ -0,0 +1,10 @@
--TEST--
Cannot use static type outside a class/trait: global function
--FILE--
<?php
function foo($x): static {};
?>
--EXPECTF--
Fatal error: Cannot use "static" when no class scope is active in %s on line %d

View File

@@ -0,0 +1,13 @@
--TEST--
Relative class types can be used for closures as it may be bound to a class
--FILE--
<?php
$fn1 = function($x): self {};
$fn2 = function($x): parent {};
$fn3 = function($x): static {};
?>
DONE
--EXPECT--
DONE

View File

@@ -0,0 +1,27 @@
--TEST--
Eval Class definition should not leak memory when using compiled traits
--FILE--
<?php
trait TraitCompiled {
public function bar(): self { return new self; }
}
const EVAL_CODE = <<<'CODE'
class A {
use TraitCompiled;
}
CODE;
eval(EVAL_CODE);
$a1 = new A();
$a2 = $a1->bar();
var_dump($a2);
?>
DONE
--EXPECT--
object(A)#2 (0) {
}
DONE

View File

@@ -0,0 +1,27 @@
--TEST--
Eval code should not leak memory when using traits
--FILE--
<?php
const EVAL_CODE = <<<'CODE'
trait TraitEval {
public function bar(): self { return new self; }
}
CODE;
eval(EVAL_CODE);
class A {
use TraitEval;
}
$a1 = new A();
$a2 = $a1->bar();
var_dump($a2);
?>
DONE
--EXPECT--
object(A)#2 (0) {
}
DONE

View File

@@ -0,0 +1,15 @@
--TEST--
Cannot use a trait which references parent as a type in a class with no parent, single type
--FILE--
<?php
trait TraitExample {
public function bar(): parent { return parent::class; }
}
class A {
use TraitExample;
}
?>
DONE
--EXPECT--
DONE

View File

@@ -0,0 +1,15 @@
--TEST--
Cannot use a trait which references parent as a type in a class with no parent, nullable type
--FILE--
<?php
trait TraitExample {
public function bar(): ?parent { return parent::class; }
}
class A {
use TraitExample;
}
?>
DONE
--EXPECT--
DONE

View File

@@ -0,0 +1,15 @@
--TEST--
Cannot use a trait which references parent as a type in a class with no parent, union type
--FILE--
<?php
trait TraitExample {
public function bar(): int|parent { return parent::class; }
}
class A {
use TraitExample;
}
?>
DONE
--EXPECT--
DONE

View File

@@ -0,0 +1,15 @@
--TEST--
Cannot use a trait which references parent as a type in a class with no parent, DNF type
--FILE--
<?php
trait TraitExample {
public function bar(): (X&Y)|parent { return parent::class; }
}
class A {
use TraitExample;
}
?>
DONE
--EXPECT--
DONE