Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fatal error: class and trait define the same constant in the composition of child class in case constant in trait is equal to constant in child class #9272

Open
MaXal opened this issue Aug 8, 2022 · 2 comments

Comments

@MaXal
Copy link

MaXal commented Aug 8, 2022

Description

The following code:

<?php
trait T {
    public const a = C2::b;
}
class C1 {
    use T;
    const b = 1;
}
class C2 extends C1  {
    use T;
    const b = 2;
}
echo C1::a;
echo C2::a;

Resulted in this output:

Fatal error: C1 and T define the same constant (a) in the composition of C2. However, the definition differs and is considered incompatible. Class was composed in /in/riAnX on line 9

But I expected this output instead:

22

It's not clear to me why this code is incorrect, but at the same time, the following works:

<?php
trait T {
    public const a = self::b;
}
class C1 {
    use T;
    const b = 1;
}
class C2 extends C1  {
    use T;
    const b = 2;
}
echo C1::a;
echo C2::a;

and outputs

11

PHP Version

8.2

Operating System

No response

@sj-i
Copy link
Contributor

sj-i commented Aug 8, 2022

Hmm, I'm not sure what to do here. Surely it's buggy, but I doubt it's easily fixable.

This isn't only for trait constants. For trait properties, this behaves the same too since PHP 5.4.
https://3v4l.org/htBnW

Early bindings of classes using traits are not supported.
So, in this case, until the compiler executor reaches the definition (DECLARE_CLASS) of C2, C2::b might be a reference to an undefined class constant that resolves to null.

For self::b, it's resolved at runtime, so doesn't cause any problems.

Edit:
No, I was wrong. A reference to an undefined class constant should trigger error. I'll look into it more.

@cmb69
Copy link
Member

cmb69 commented Oct 20, 2022

The relevant point is already shown by the warning, which is emitted by this script:

Warning: Uncaught Error: Class "C2" not found in gh9272.php:4

During execution, DECLARE_CLASS string("c1") fails to resolve the AST expression of the constant, because C2 can't be found (because this is late bound, too), and from there is goes south.

Surely it's buggy, but I doubt it's easily fixable.

I agree. And the given code appears to be quite an edge-case. I'd say we should just document the limitation, although I wouldn't know how to do this without requiring the knowledge of https://www.npopov.com/2021/10/20/Early-binding-in-PHP.html (which is not even roughly covered in the PHP manual yet).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants