Skip to content

[ hh_client --lint ] False positive for 5607, equality checks a generic value to a typed value is not always false #8940

@lexidor

Description

@lexidor

Describe the bug
Given the expression $expression_resolving_to_generic_type === $expression_resolving_to_a_known_type, lint rule 5607 should not emit an error if the generic type has any overlap with the known type.

Standalone code, or other way to reproduce the problem

function is_life<T>(T $t): (bool, T) {
  return tuple($t === 42, $t);
}

Steps to reproduce the behavior:

  1. hh_client --lint file.hack

Expected behavior

No linter errors! Because T does not have a constraint that says it can not be an int, therefore it can be an int. $t === 42 is not always false.

Actual behavior

Lint[5607] Invalid comparison: This expression will always return false.
A value of type T can never be equal to a value of type int [1]

file.hack:2:16
    1 | function is_life<T>(T $t): (bool, T) {
[1] 2 |   return tuple($t === 42, $t);
    3 | }

Environment

  • Operating system

Ubuntu 20.04.

  • Installation method

apt-get with dl.hhvm.com repository

  • HHVM Version

Please include the output of hhvm --version and hh_client --version

HipHop VM 4.137.0 (rel) (non-lowptr)
Compiler: 1637698090_520463089
Repo schema: d90319777b5acb5402a80af5652b95f8dcdd4048
hackc-261ee251a4f119d21a986be5fb0c88d2e404b515-4.137.0

Additional context
This version compares ?T to ?int, which is also a false positive.

Lint[5607] Invalid comparison: This expression will always return false.
A value of type ?T can never be equal to a value of type ?int [1]

file.hack:3:16
    1 | function is_life<T>(bool $unknown_to_typechecker, ?T $t): (bool, ?T) {
    2 |   $maybe_null = $unknown_to_typechecker ? null : 42;
[1] 3 |   return tuple($t === $maybe_null, $t);
    4 | }

But this false positive goes away for always-null checks.

function is_life<T>(bool $unknown_to_typechecker, ?T $t): (bool, ?T) {
  $maybe_null = $unknown_to_typechecker ? null : null;
  return tuple($t === $maybe_null, $t);
}
No lint errors!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions