Hi Larry

On Thu, Jan 22, 2026 at 6:19 PM Larry Garfield <[email protected]> wrote:
>
> On Thu, Jan 22, 2026, at 10:41 AM, Ilija Tovilo wrote:
> >
> > As mentioned, the rules for when static can be inferred are slightly
> > esoteric. For example, your code may be calling Foo::bar(), which
> > _looks_ like a static call, but could actually be an instance
> > grand-parent call (https://3v4l.org/uDi8W#v8.4.14). If you were to
> > remove this ambiguous call, and the closure could now be inferred as
> > static, it would be bad if existing Closure::bind[To]() calls would
> > break because they provide an object. For this reason,
> > Closure::bind[To]() will _accept but discard_ objects only for
> > closures inferred as static.
>
> Ah, so it's just a "don't break code that's already wrong but not harmfully 
> so" feature.

I wouldn't consider it wrong to not mark functions as static that
could be static, otherwise there wouldn't be a need for this
optimization. Consequently, it would also not be wrong to attempt to
Closure::bind() an object to such a closure, which is why I felt it
was important to keep this case working. The caveat here being that
the object is discarded, so ReflectionFunction::getClosureThis() will
still return NULL.

> I'm OK with that, but please add that to the RFC.

I did not plan to make an RFC for this, given the BC breaks are mostly
theoretical. But if anybody objects, I'm happy to create one.

Ilija

On Thu, Jan 22, 2026 at 6:19 PM Larry Garfield <[email protected]> wrote:
>
> On Thu, Jan 22, 2026, at 10:41 AM, Ilija Tovilo wrote:
> > Hi Larry
> >
> > On Thu, Jan 22, 2026 at 5:03 PM Larry Garfield <[email protected]> 
> > wrote:
> >>
> >> On Wed, Jan 21, 2026, at 1:52 PM, Ilija Tovilo wrote:
> >> >
> >> > I've created a PR implementing two new optimizations for closures. [1]
> >> > There are some theoretical BC breaks, so please let me know if any of
> >> > them are of concern to you.
> >> >
> >> > Of note is that Closure::bind() and Closure::bindTo() usually throw
> >> > when attempting to bind an object to a static closure. In my PR, this
> >> > is explicitly allowed only for closures that are inferred as static,
> >> > but not those that are explicitly static.
> >> >
> >> >
> >> > [1] https://github.com/php/php-src/pull/19941
> >>
> >> This all looks great, Ilija!  I am not concerned about the BC mentions, as 
> >> they seem to be accurate anyway.
> >>
> >> My one question is about the bindTo() on an inferred static closure.  What 
> >> purpose does that serve?  I'm assuming that anything that mentions $this 
> >> in its body won't be marked static, and if it doesn't have $this I don't 
> >> get what value bindTo() would have.  What's the use case for making an 
> >> exception here?
> >
> > Oops, it seems I've left out some details I was meaning to add. The
> > aim for allowing the passing of objects to Closure::bind[To]() is to
> > retain BC when a closure can suddenly be inferred as static due to
> > seemingly unrelated changes.
> >
> > As mentioned, the rules for when static can be inferred are slightly
> > esoteric. For example, your code may be calling Foo::bar(), which
> > _looks_ like a static call, but could actually be an instance
> > grand-parent call (https://3v4l.org/uDi8W#v8.4.14). If you were to
> > remove this ambiguous call, and the closure could now be inferred as
> > static, it would be bad if existing Closure::bind[To]() calls would
> > break because they provide an object. For this reason,
> > Closure::bind[To]() will _accept but discard_ objects only for
> > closures inferred as static.
> >
> > Ilija
>
> Ah, so it's just a "don't break code that's already wrong but not harmfully 
> so" feature.  I'm OK with that, but please add that to the RFC.
>
> --Larry Garfield

Reply via email to