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

Impossible intersection types are not checked at compile time #3706

Open
Kenny1911 opened this issue Sep 1, 2024 · 7 comments
Open

Impossible intersection types are not checked at compile time #3706

Kenny1911 opened this issue Sep 1, 2024 · 7 comments
Labels
bug Documentation contains incorrect information Status: Needs Triage

Comments

@Kenny1911
Copy link

Description

The following code:

<?php

class Foo {}

class Bar {}

function test(Foo&Bar $arg): void {}

https://3v4l.org/sKIr0

I use intersection type Foo&Bar for function argument.

Actually, there is no type that would be comparable to Foo&Bar. Therefore, Foo&Bar is equivalent to the type never.

If i use never in argument type, PHP Fatal Error will be thrown. But if i use Foo&Bar, no error will occur.

Resulted in this output:

Nothing

But I expected this output instead:

PHP Fatal error:  Foo&Bar cannot be used as a parameter type

PHP Version

PHP 8.3.11

Operating System

Ubuntu 20.04

@Kenny1911 Kenny1911 added bug Documentation contains incorrect information Status: Needs Triage labels Sep 1, 2024
@iluuu1994
Copy link
Member

Hi @Kenny1911. This is something static analysis can help you with. IMO, this doesn't need solving in the PHP engine, as it will just add more runtime burden. @Girgias thoughts?

https://phpstan.org/r/a1a9efce-9725-40d1-818a-595a25e65c12

@vudaltsov
Copy link
Contributor

@iluuu1994 , however PHP does check int&float, for example. Is it difficult to check this as well?

@iluuu1994
Copy link
Member

iluuu1994 commented Sep 1, 2024

however PHP does check int&float, for example

That's not quite the same:

Fatal error: Type int cannot be part of an intersection type

The engine makes assertions about members of intersection types being class types.

I'm not sure about hard, but at least for Foo&Bar, it would necessarily have to happen at runtime, when both types are available.

@Girgias
Copy link
Member

Girgias commented Sep 1, 2024

@iluuu1994 , however PHP does check int&float, for example. Is it difficult to check this as well?

Yes, as currently class-types are not loaded at compile time except where necessary (for variance checks).

Changing this behaviour would at least require an RFC to allow the engine to autoload classes where previously it was not required.

Checking for int&float is easy as they are built-in types.

@iluuu1994
Copy link
Member

iluuu1994 commented Sep 1, 2024

Right. Given this would either require to:

  1. delay the type check until both types are loaded, for which he have no trigger
  2. change behavior and autoload prematurely

I don't think this should be solved.

@cmb69
Copy link
Member

cmb69 commented Sep 1, 2024

I agree to WONTFIX, but we should probably improve the documentation on intersection types.

@iluuu1994 iluuu1994 transferred this issue from php/php-src Sep 1, 2024
@iluuu1994 iluuu1994 changed the title Argument type is intersection, comprised of the classes without common parent Impossible intersection types are not checked at compile time Sep 1, 2024
@Girgias
Copy link
Member

Girgias commented Sep 9, 2024

Just to note, that this is described in the type declaration page of the documentation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Documentation contains incorrect information Status: Needs Triage
Projects
None yet
Development

No branches or pull requests

5 participants