Skip to content

[ hh_client --lint | Lint[5607] ] False negative, comparing an interface to a scalar does not emit a warning #9563

Open
@lexidor

Description

Describe the bug
Comparing a scalar to an interface (other than Stringish and XHPChild), should emit a warning Lint[5607] Invalid comparison: This expression will always return false..

Standalone code, or other way to reproduce the problem

interface SomeInterface {}
class SomeClass {}

function caught(string $string, SomeClass $class)[]: bool {
    return $string === $class;
}

function uncaught(string $string, SomeInterface $interface)[]: bool {
    return $string === $interface;
}

Steps to reproduce the behavior:

  1. hh_client --lint filename.hack

Expected behavior

Two lint errors (one in caught, and one in uncaught)

Actual behavior

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

src/bug.hack:5:12
    3 | 
    4 | function caught(string $string, SomeClass $class)[]: bool {
[1] 5 |     return $string === $class;
    6 | }
    7 | 

Environment

  • Operating system 'Ubuntu'
  • Installation method 'hhvm/hhvm on dockerhub'
  • HHVM Version
HipHop VM 4.168.2 (rel) (non-lowptr)
Compiler: 1674167390_239081398
Repo schema: b20d78caba71435cd4028326fcf28ee798279c8e
hackc-af2b2722e8cac3d0bc5fe213eeb16d7296da458f-4.168.2

Additional context
I think there may be a special case for Stringish and/or XHPChild
that is tripping this linter up.
Stringish === string is a valid comparison,
since string ""implements"" Stringish.
Even though interfaces are non-exclusive, string only implements
XHPChild and Stringish, so for the purposes of this check,
implementing SomeInterface implies not string.

This issue also reproduces for all scalars (int, bool, float, string),
so int === SomeInterface should always be false.
The only common interface between a value of SomeInterface and int
is XHPChild, which can be eliminated with the same logic that
Stringish could for the string case above.

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