Skip to content

Fix #74872 - Disambiguate the source of a trait alias when possible #2616

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

Closed
wants to merge 2 commits into from

Conversation

pmmaga
Copy link
Contributor

@pmmaga pmmaga commented Jul 8, 2017

Link for bugsnet: https://bugs.php.net/bug.php?id=74872

Cases where two traits with a duplicate method name are added in the same use block will still be ambiguous.

@pmmaga pmmaga changed the title Fix #74872 - Disambiguate the source of a trait alias where possible [WIP] Fix #74872 - Disambiguate the source of a trait alias when possible Jul 8, 2017
@pmmaga pmmaga force-pushed the bug-74872 branch 2 times, most recently from 7ff5bc5 to 7d3f8a5 Compare July 8, 2017 23:52
@pmmaga pmmaga changed the title [WIP] Fix #74872 - Disambiguate the source of a trait alias when possible Fix #74872 - Disambiguate the source of a trait alias when possible Jul 9, 2017
@krakjoe krakjoe added the Bug label Jul 9, 2017
@krakjoe
Copy link
Member

krakjoe commented Jul 10, 2017

Please don't include NEWS patches in pull requests, conflicts emerge too quickly ... the merger does the NEWS change when they pull in the PR.

@krakjoe
Copy link
Member

krakjoe commented Jul 12, 2017

@nikic @bwoebi @dstogov can I get a thumbs up from one of you please ?

@pmmaga
Copy link
Contributor Author

pmmaga commented Jul 18, 2017

A little more background on each commit and why they are still separate:

  • The first one fixes the original issue as it was reported. Meaning that it enables us to know from which trait a method is coming and allowing it to be added to the class if and only if, the receiving class ALSO implements a method with the same name.
  • The second one allows the fix to be extended to cases where the receiving class does not implement a method with the same name as the methods brought by the traits. Meaning that aliased methods will no longer collide as it is possible to call them unambiguously.
  • The third one enables the better collision message that was commented out on the code. With these fixes it should now be possible to show the better error message on all cases.

I'm not sure if the last one should be applied to GA branches as it will change an error message.

@pmmaga
Copy link
Contributor Author

pmmaga commented Jul 19, 2017

I have removed the second commit because allowing a collision when the methods are aliased would still cause issues when that method is being called by it's original name in other methods of the same trait.
As an example:

trait T1 {
    function originalName() {
        echo 'Yeah!' . PHP_EOL;
    }
    
    function hi(){
        $this->originalName();
    }
}

trait T2 {
    function originalName() {
        echo 'No!' . PHP_EOL;
    }
}

class C {
    use T2;
    use T1 {
        originalName as aliasedName;
    }
}

$c = new C();
$c->aliasedName(); // Would output "Yeah!"
$c->hi(); // Would output "No!"

@pmmaga
Copy link
Contributor Author

pmmaga commented Oct 12, 2017

Pinging the same that were pinged above. @bwoebi @nikic @dstogov Can any of you review this?

@KalleZ
Copy link
Member

KalleZ commented Mar 2, 2019

@pmmaga are you still actively working on this? It seems like your ping did not do anything, so just putting a friendly nudge here. @nikic perhaps?

@pmmaga
Copy link
Contributor Author

pmmaga commented Mar 3, 2019

This needs a rebase as I haven't touched it for a long time. I'll try to get it up to date soon.

@pmmaga pmmaga changed the base branch from master to PHP-7.2 April 24, 2019 18:31
@pmmaga
Copy link
Contributor Author

pmmaga commented Apr 24, 2019

Freshly rebased on 7.2. I'd like a thumbs up to merge this

@nikic nikic self-requested a review April 24, 2019 19:59
@nikic
Copy link
Member

nikic commented Apr 24, 2019

At least as implemented this breaks ABI, so can only go into 7.4.

ZSTR_VAL(fn->common.scope->name),
ZSTR_LEN(fn->common.scope->name),
ZSTR_VAL(alias->trait_names[i]),
ZSTR_LEN(alias->trait_names[i])) == 0) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can use zend_string_equals_ci here.


class Test
{
use Trait1 {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if we make this use Trait1, Trait3 and Trait3 also has an init method? If I'm reading your code right, it's just going to pick one of them. But I think this should be an error.

I'm wondering if an absolute trait method reference shouldn't be required when multiple traits are used in one block.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right now it still picks one of them in that case. The currrent behavior is to disambiguate when possible and keep the old behavior (pick one) when it's not possible to know. But yes, I think it's a good idea to error in those cases.

I've started porting this to 7.4 but still have to redo the opcache part. So I'll also rework that.

@krakjoe
Copy link
Member

krakjoe commented Oct 2, 2019

@pmmaga can we get a status update here please ?

@nikic
Copy link
Member

nikic commented Mar 3, 2020

I've put up an alternative fix at #5232.

@pmmaga
Copy link
Contributor Author

pmmaga commented Mar 3, 2020

Closed in favor of the PR above

@pmmaga pmmaga closed this Mar 3, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants