Skip to content

Commit 35c377a

Browse files
committed
fix instanceof
Signed-off-by: Robert Landers <landers.robert@gmail.com>
1 parent 8341b37 commit 35c377a

13 files changed

Lines changed: 39 additions & 34 deletions

UPGRADING

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ PHP 8.6 UPGRADE NOTES
211211
`Box<string>`) synthesises a separate class entry whose canonical
212212
name is spelled out (`"Box<int>"`), registered in the class table,
213213
and visible through `get_class()`, `var_dump`, and
214-
`instanceof Box<int>`. Function- and method-level generics are
214+
`instanceof Box::<int>`. Function- and method-level generics are
215215
reified per call frame: each call carries its own type-argument
216216
table, with no persistent `id<int>` function entry (avoiding
217217
unbounded growth). Closures and generators preserve the table so
@@ -224,7 +224,7 @@ PHP 8.6 UPGRADE NOTES
224224
actually pass at this slot." Reified type arguments are kept on a
225225
side table and consulted at well-defined runtime points: monomorph
226226
synthesis, turbofish argument validation, deferred lookups for
227-
`instanceof Box<T>` / `catch (Box<T> $e)`, bare `T`-ref resolution
227+
`instanceof Box::<T>` / `catch (Box<T> $e)`, bare `T`-ref resolution
228228
(`instanceof T`, `catch (T $e)`, `new T()`, `T::method()`),
229229
inheritance linking, and Reflection.
230230
. It is now possible to use reference assign on WeakMap without the key

UPGRADING.INTERNALS

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ PHP 8.6 INTERNALS UPGRADE NOTES
231231
- ZEND_FETCH_CLASS_TYPE_PARAM_CLASS (8) — class-level bare
232232
T-ref; resolves via the called-scope walk.
233233
- ZEND_FETCH_CLASS_GENERIC_DEFERRED (9) — generic named type
234-
whose args contain T-refs (`instanceof Box<T>`,
234+
whose args contain T-refs (`instanceof Box::<T>`,
235235
`catch (Box<T> $e)`). The args_id sits in the high bits of
236236
op.num and points into the op_array's
237237
generic_types->turbofish_args side table.

Zend/tests/generics/erasure/instanceof_args_discarded.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Erasure: instanceof on a non-generic class with type arguments is a compile-time
44
<?php
55
class C {}
66
$c = new C;
7-
var_dump($c instanceof C<int>);
7+
var_dump($c instanceof C::<int>);
88
?>
99
--EXPECTF--
1010
Fatal error: Type arguments are not allowed on non-generic class C in %s on line %d

Zend/tests/generics/errors/type_args_on_non_generic_instanceof.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Type arguments on a non-generic class in `instanceof` are a compile-time error
44
<?php
55
class Plain {}
66
$x = new Plain;
7-
var_dump($x instanceof Plain<int>);
7+
var_dump($x instanceof Plain::<int>);
88
?>
99
--EXPECTF--
1010
Fatal error: Type arguments are not allowed on non-generic class Plain in %s on line %d

Zend/tests/generics/reification/instanceof_distinguishes_monos.phpt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ $ba = new Box::<Animal>();
1212

1313
// Each mono extends the bare class but is otherwise distinct.
1414
var_dump($bd instanceof Box); // true: parent-name chain
15-
var_dump($bd instanceof Box<Dog>); // true: same canonical mono
16-
var_dump($bd instanceof Box<Animal>); // false: invariant distinction
17-
var_dump($ba instanceof Box<Dog>); // false
18-
var_dump($ba instanceof Box<Animal>); // true
15+
var_dump($bd instanceof Box::<Dog>); // true: same canonical mono
16+
var_dump($bd instanceof Box::<Animal>); // false: invariant distinction
17+
var_dump($ba instanceof Box::<Dog>); // false
18+
var_dump($ba instanceof Box::<Animal>); // true
1919
?>
2020
--EXPECT--
2121
bool(true)

Zend/tests/generics/reification/instanceof_nested_t_ref.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
--TEST--
2-
Reification: nested T-refs (instanceof Outer<Box<T>>) substitute through and resolve the outermost monomorph
2+
Reification: nested T-refs (instanceof Outer::<Box<T>>) substitute through and resolve the outermost monomorph
33
--FILE--
44
<?php
55
class Box<U> {}
66
class Outer<V> {}
77

88
class Holder<T> {
99
public function isOuterOfBox(mixed $x): bool {
10-
return $x instanceof Outer<Box<T>>;
10+
return $x instanceof Outer::<Box<T>>;
1111
}
1212
}
1313

Zend/tests/generics/reification/instanceof_variance.phpt

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,23 +15,23 @@ $dogProd = new Producer::<Dog>();
1515
$animalCons = new Consumer::<Animal>();
1616

1717
// Invariant: only same-arg passes.
18-
var_dump($dogBox instanceof Box<Dog>); // true (identical)
19-
var_dump($dogBox instanceof Box<Animal>); // false
20-
var_dump($dogBox instanceof Box<Cat>); // false
18+
var_dump($dogBox instanceof Box::<Dog>); // true (identical)
19+
var_dump($dogBox instanceof Box::<Animal>); // false
20+
var_dump($dogBox instanceof Box::<Cat>); // false
2121

2222
// Covariant: Dog <: Animal, so Producer<Dog> <: Producer<Animal>.
23-
var_dump($dogProd instanceof Producer<Animal>); // true
24-
var_dump($dogProd instanceof Producer<Cat>); // false
25-
var_dump($dogProd instanceof Producer<Dog>); // true
23+
var_dump($dogProd instanceof Producer::<Animal>); // true
24+
var_dump($dogProd instanceof Producer::<Cat>); // false
25+
var_dump($dogProd instanceof Producer::<Dog>); // true
2626

2727
// Contravariant: Animal :> Dog, so Consumer<Animal> <: Consumer<Dog>.
28-
var_dump($animalCons instanceof Consumer<Dog>); // true
29-
var_dump($animalCons instanceof Consumer<Cat>); // true
30-
var_dump($animalCons instanceof Consumer<Animal>);// true
28+
var_dump($animalCons instanceof Consumer::<Dog>); // true
29+
var_dump($animalCons instanceof Consumer::<Cat>); // true
30+
var_dump($animalCons instanceof Consumer::<Animal>);// true
3131

3232
// Reverse contravariant fails.
3333
$dogCons = new Consumer::<Dog>();
34-
var_dump($dogCons instanceof Consumer<Animal>); // false
34+
var_dump($dogCons instanceof Consumer::<Animal>); // false
3535
?>
3636
--EXPECT--
3737
bool(true)

Zend/tests/generics/reification/instanceof_with_t_ref_class_level.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
--TEST--
2-
Reification: instanceof Box<T> with class-level T resolves against the called scope's monomorph args
2+
Reification: instanceof Box::<T> with class-level T resolves against the called scope's monomorph args
33
--FILE--
44
<?php
55
class Box<T> {}
66

77
class Outer<T> {
88
public function isBox(mixed $x): bool {
9-
return $x instanceof Box<T>;
9+
return $x instanceof Box::<T>;
1010
}
1111
}
1212

Zend/tests/generics/reification/instanceof_with_t_ref_function_level.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
--TEST--
2-
Reification: instanceof Box<T> with function-level T resolves against the current frame's turbofish bindings
2+
Reification: instanceof Box::<T> with function-level T resolves against the current frame's turbofish bindings
33
--FILE--
44
<?php
55
class Box<T> {}
66

77
function isBoxOf<T>(mixed $x): bool {
8-
return $x instanceof Box<T>;
8+
return $x instanceof Box::<T>;
99
}
1010

1111
var_dump(isBoxOf::<int>(new Box::<int>)); // true

Zend/tests/generics/reification/monomorph_implements_substitution.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Reification: a monomorph of `B<T> implements I<T>` should report `is_a I<bound>`
44
<?php
55
// Regression: when `B<T> implements I<T>` is monomorphized as `B<string>`,
66
// the implements binding has to be substituted so that `B<string>` is also
7-
// known to implement `I<string>`. Otherwise `instanceof I<string>` /
7+
// known to implement `I<string>`. Otherwise `instanceof I::<string>` /
88
// `is_a(..., 'I<string>')` returns false even though the type relationship
99
// holds, and property writes typed `I<string>` reject `B<string>` values.
1010

0 commit comments

Comments
 (0)