Skip to content

Conversation

simPod
Copy link
Contributor

@simPod simPod commented Aug 9, 2021

Remove CS checks for missing traversable type hints

I propose to disable these sniffs as we have and already adopted tools that are more capable to check for such issues (PHPStan/Psalm).

WDYT? If we agree, I'll go and adopt related tests.


Basic example

PHPStan complains about not getting a type spec: https://phpstan.org/r/9a2a974a-d647-4c95-99d1-e87ef7fc9207

function food(iterable $i): void
{
	return;
}

Implementing a method

❌ Missing type hint is complained about https://phpstan.org/r/cebc3f17-4c08-4e6f-a6d8-cfae8ebc4338

interface I {
	public function foo(): iterable;
}

final class C implements I {
	public function foo(): iterable {
		return [];
	}
}

✅ Adding a type hint on the interface fixes the error without having a need to also provide @inheritDoc to all implementations. Implementations inherit that from interface by default so @inheritDoc becomes redundant in most cases we use it nowadays.
Phpstan is not limited to single file evaluation like phpcs but can evaluate the whole context.

https://phpstan.org/r/6c748d83-62b3-4c94-b22b-4d852696050e

interface I {
	/** @return iterable<mixed> */
	public function foo(): iterable;
}

final class C implements I {
	public function foo(): iterable {
		return [];
	}
}

@malarzm
Copy link
Member

malarzm commented Aug 9, 2021

PHPStan or Psalm check for these better.

They check them once the spec is written no? It's up to CS to enforce specifying what's inside a traversable. Unless I'm missing knowledge about some features in those tools :)

@simPod
Copy link
Contributor Author

simPod commented Aug 9, 2021

What spec do you mean? 🤔

I should've added a playground link though: https://phpstan.org/r/198b1899-3695-4bf6-b158-0c3f3445095d

malarzm
malarzm previously approved these changes Aug 9, 2021
Copy link
Member

@malarzm malarzm left a comment

Choose a reason for hiding this comment

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

Ah cool, so PHPStan does emit an error 👍

spawnia
spawnia previously approved these changes Aug 9, 2021
Copy link

@spawnia spawnia left a comment

Choose a reason for hiding this comment

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

PHPStan really is smarter about typehints.

@simPod simPod dismissed stale reviews from spawnia and malarzm via 454031e August 30, 2021 08:34
@simPod simPod force-pushed the drop-sniffs branch 4 times, most recently from 7a67cdf to fa41e71 Compare August 30, 2021 08:49
PHPStan or Psalm check for these better
@simPod simPod marked this pull request as ready for review August 30, 2021 08:55
@simPod simPod requested a review from a team as a code owner August 30, 2021 08:55
@simPod simPod requested a review from malarzm August 30, 2021 08:55
@Ocramius
Copy link
Member

Does psalm already report on missing iterable types?

@simPod
Copy link
Contributor Author

simPod commented Aug 30, 2021

I guess:

https://psalm.dev/r/6189d0e1e3 without type
https://psalm.dev/r/dacb0340d2 with type

@Ocramius
Copy link
Member

Yeh, but that still allows passing on an iterable<mixed> to somebody else (when not consuming it directly, or when declaring a return type).

In practice, this iterable rule has been one of the biggest drivers in type safety a couple years ago, and dropping it still allows for declaring untyped iterables in abstract types 🤔

Before calling it "done", it would be best to have this also in psalm mixed rules, IMO.

@simPod
Copy link
Contributor Author

simPod commented Aug 30, 2021

The point here was to drop the phpcs check as we have a smarter and more bulletproof alternative in PHPStan. So even though Psalm does no have the feature parity in this matter now, it does not seem like an obstacle to me.
Not having to spam inheritDoc in every implementation is a nice bonus.

TBH I think we all have to use both psalm and phpstan simultaneously to be safe.

@Ocramius
Copy link
Member

Not really: I stopped using phpstan for my own work (also OSS), and will likely pick it up again in a few years, if things change 🤷‍♀️

@malarzm
Copy link
Member

malarzm commented Aug 30, 2021

We still tend to use both PHPStan and Psalm in all major Doctrine repositories so there's no need for an additional CS rule

@malarzm
Copy link
Member

malarzm commented Aug 30, 2021

@doctrine/coding-standard-approvers I'm not sure if this can be merged as a patch release so I'm deferring clicking merge button to somebody more informed :)

Copy link
Member

@Ocramius Ocramius left a comment

Choose a reason for hiding this comment

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

in all major Doctrine repositories

These CS rules are also (and mostly) in use outside the scope of doctrine/*, hence the argument I made above

@simPod
Copy link
Contributor Author

simPod commented Aug 30, 2021

Though in my opinion we can drop features here that are superseded by other tools if those tools are not newborn or experimental or w.e. and other repositories should too. That was the point of this PR.
Other repositories can eventually reenable those.

@morozov
Copy link
Member

morozov commented Aug 31, 2021

I have been always thinking of the coding standard requiring type annotations as a way to enable static analysis tools, not as a solution on its own. As long as PHPStan no longer needs it, I'd say we could disable this requirement in the coding standard. Those meaningless {@inheritDoc}s alone would be a good reason to do that.

Eventually, I'd like to see this tool focusing on code formatting which it's originally designed for, not on static analysis.

@simPod simPod requested a review from morozov November 11, 2021 08:27
simPod added a commit to cdn77/coding-standard that referenced this pull request Jan 12, 2022
simPod added a commit to cdn77/coding-standard that referenced this pull request Jan 14, 2022
@greg0ire
Copy link
Member

Today, I found that using a type alias to replace occurrences of array<int, int|string|Type|null>|array<string, int|string|Type|null> with ArrayOfTypes results in phpcs erroring out with @param annotation of method \Doctrine\DBAL\Query\QueryBuilder::setParameters() does not specify type hint for items of its traversable parameter $types.

So now I'd say this rule is making the maintenance harder: after that refactoring I was planning to narrow down int to Connection::PARAM_*|ParameterType::*, but now it's going to be verbose and impractical.

@Ocramius can you please reconsider?

As for the target branch, I think it's ok to target 9.0.x since it's unlikely to make build fail.

@Ocramius
Copy link
Member

Ocramius commented Feb 11, 2022

using a type alias to replace occurrences ... results in phpcs erroring out

Sounds like a bug, rather than related to this RFC (which proposes dropping the rule overall).

@Ocramius can you please reconsider?

No, not really - it's something that helped me on countless projects to get type declarations in, even when phpstan/phpstan or vimeo/psalm were installed. It has and is a huge driver for increasing type safety inside codebases.

@greg0ire
Copy link
Member

greg0ire commented Feb 11, 2022

I reported the bug here FTR: slevomat/coding-standard#1334, hopefully it's fixable. If not, we might consider disabling it on a per-project basis.

@kukulich
Copy link
Contributor

It should be fixable :)

@simPod
Copy link
Contributor Author

simPod commented Sep 6, 2022

Ping me if this is wished for in the future.

@simPod simPod closed this Sep 6, 2022
@simPod simPod deleted the drop-sniffs branch September 11, 2022 11:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants