== Why is this an issue?

Kotlin provides the operators `as` and `as?` to cast an expression to a specific type,
and `is` to check the assignment compatibility with a type.
These operators are used for downcasts, smart casts, and run-time type checking.

In case the `as` or `as?` operator is used for upcasting from a subtype to a supertype,
the cast is redundant as it has no effect and can never fail.
If a specific type is expected, an expression of a subtype can always be inserted
without casting (Substitution Principle and Assignment Compatibility).

Likewise, the `is` operator is redundant and will always return `true` if the type of the expression on the left
side is assignment compatible with the type on the right.

=== What is the potential impact?

==== Code redundancy

Since the operation will always succeed and has no side effects, it is pointless to use it.
Conditions with `is` will lead to dead code branches because they will always or never be satisfied.

== How to fix it

Remove the operator and all dead code branches that result from it, or investigate why the expression that is cast or checked has
an unexpected compile-time type.

=== Code examples

==== Noncompliant code example

[source,kotlin,diff-id=1,diff-type=noncompliant]
----
fun types(value: Int, elements: List<Number>) {
    val a: Number = value as Number // Noncompliant, Int instance is always a Number
    val b: Number = value as? Number // Noncompliant, Int instance is always a Number

    val text = if (value is Number) { // Noncomplient, else-branch is dead code
        "happens always"
    } else {
        "impossible"
    }
}
----

==== Compliant solution

[source,kotlin,diff-id=1,diff-type=compliant]
----
fun types(value: Number, elements: List<Number>) {
    val a: Int = value as Int // Compliant, Number instance could be an Int
    val b: Int = value as? Int // Compliant, Number instance could be an Int

    val text = if (value is Int) { // Compliant, both branches reachable
        "impossible"
    } else {
        "happens always"
    }
}
----

== Resources

=== Documentation

* https://kotlinlang.org/docs/typecasts.html[Kotlin API Docs, Type checks and casts]

=== Articles & blog posts

* https://en.wikipedia.org/wiki/Liskov_substitution_principle[Wikipedia, Liskov substitution principle]
