---------- Forwarded message --------- 
From: Robert Landers landers.robert@gmail.com 
Date: Sat, Feb 24, 2024 at 9:20 AM 
Subject: History of traits + inheritance 
To: internals internals@lists.php.net
I'm asking for a history lesson if anyone knows, as I couldn't find 
any relevant information in externals and it appears to have been this 
way for awhile, with a minor exception, which is the part I'm curious 
about.
Consider the following code:
abstract class A { 
abstract protected function test(); 
}
class C extends A { 
protected function test() 
{ 
return 'C'; 
} 
}
class D extends A { 
public function prnt(A $a) { 
echo $a->test(); 
}
protected function test() {
    return 'D';
}
}
$d = new D; 
$c = new C;
$d->prnt($d); 
$d->prnt($c);
This behaves exactly how you'd expect it to behave "DC" is printed on 
the screen.
However, if we add a trait:
trait E { 
protected function test() { 
return 'E'; 
} 
}
and implement it:
class B extends A { 
use E; 
}
$d->prnt($b);
We get the following fatal error:
Call to protected method B::test() from scope D
Except that in 5.4.7 - 5.4.10, the "expected" output is given:
DCE
To me, this breaks the whole idea usually given that "traits are 
fancy, compiler assisted copy-paste" since clearly it gives an error 
when trying to use it like that. However, I'm mostly curious as to 
what happened in 5.4.7 that "fixed" it and then was reverted after 
5.4.10. There's nothing about it in the release notes for 5.4.11, and 
nothing about it in externals (that I could dig up).
Another thing I'm curious about: is this intentional behavior or a bug 
that probably won't be fixed (or would only be fixed via an RFC)?
Robert Landers 
Software Engineer 
Utrecht NL
PS. bumping this because it didn't show up on externals so I can only 
assume something didn't work.