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

EqualsAlwaysReturnsTrueOrFalse fails hard on override fun equals(other:Any) = ... #2167

Closed
mikesamuel opened this issue Dec 5, 2019 · 3 comments
Milestone

Comments

@mikesamuel
Copy link

A minimal repro code sample below.
It looks like the Detekt pass fails when there are zero return statements, e.g. when using fun equals(...) = expression syntax.

Stack Trace

The original exception message was: List is empty.
Running detekt '1.2.0' on Java '11.0.5-ea+10-post-Ubuntu-0ubuntu1' on OS 'Linux'.
If the exception message does not help, please feel free to create an issue on our GitHub page.
kotlin.collections.CollectionsKt___CollectionsKt.first(_Collections.kt:196)
io.gitlab.arturbosch.detekt.rules.bugs.EqualsAlwaysReturnsTrueOrFalse.isSingleReturnWithBooleanConstant(EqualsAlwaysReturnsTrueOrFalse.kt:71)
io.gitlab.arturbosch.detekt.rules.bugs.EqualsAlwaysReturnsTrueOrFalse.returnsBooleanConstant(EqualsAlwaysReturnsTrueOrFalse.kt:63)
io.gitlab.arturbosch.detekt.rules.bugs.EqualsAlwaysReturnsTrueOrFalse.visitNamedFunction(EqualsAlwaysReturnsTrueOrFalse.kt:52)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitNamedFunction(KtVisitorVoid.java:483)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitNamedFunction(KtVisitorVoid.java:21)
org.jetbrains.kotlin.psi.KtNamedFunction.accept(KtNamedFunction.java:50)
org.jetbrains.kotlin.psi.KtElementImplStub.accept(KtElementImplStub.java:59)
org.jetbrains.kotlin.com.intellij.psi.impl.PsiElementBase.acceptChildren(PsiElementBase.java:69)
org.jetbrains.kotlin.psi.KtTreeVisitorVoid.visitElement(KtTreeVisitorVoid.java:25)
org.jetbrains.kotlin.psi.KtVisitor.visitKtElement(KtVisitor.java:24)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitKtElement(KtVisitorVoid.java:25)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitKtElement(KtVisitorVoid.java:447)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitKtElement(KtVisitorVoid.java:21)
org.jetbrains.kotlin.psi.KtVisitor.visitClassBody(KtVisitor.java:98)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitClassBody(KtVisitorVoid.java:89)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitClassBody(KtVisitorVoid.java:537)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitClassBody(KtVisitorVoid.java:21)
org.jetbrains.kotlin.psi.KtClassBody.accept(KtClassBody.kt:38)
org.jetbrains.kotlin.psi.KtElementImplStub.accept(KtElementImplStub.java:59)
org.jetbrains.kotlin.com.intellij.psi.impl.PsiElementBase.acceptChildren(PsiElementBase.java:69)
org.jetbrains.kotlin.psi.KtTreeVisitorVoid.visitElement(KtTreeVisitorVoid.java:25)
org.jetbrains.kotlin.psi.KtVisitor.visitKtElement(KtVisitor.java:24)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitKtElement(KtVisitorVoid.java:25)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitKtElement(KtVisitorVoid.java:447)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitKtElement(KtVisitorVoid.java:21)
org.jetbrains.kotlin.psi.KtVisitor.visitExpression(KtVisitor.java:182)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitExpression(KtVisitorVoid.java:169)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitExpression(KtVisitorVoid.java:659)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitExpression(KtVisitorVoid.java:21)
org.jetbrains.kotlin.psi.KtVisitor.visitDeclaration(KtVisitor.java:29)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitDeclaration(KtVisitorVoid.java:29)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitDeclaration(KtVisitorVoid.java:453)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitDeclaration(KtVisitorVoid.java:21)
org.jetbrains.kotlin.psi.KtVisitor.visitNamedDeclaration(KtVisitor.java:398)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitNamedDeclaration(KtVisitorVoid.java:381)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitNamedDeclaration(KtVisitorVoid.java:959)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitNamedDeclaration(KtVisitorVoid.java:21)
org.jetbrains.kotlin.psi.KtVisitor.visitClassOrObject(KtVisitor.java:41)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitClassOrObject(KtVisitorVoid.java:37)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitClassOrObject(KtVisitorVoid.java:465)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitClassOrObject(KtVisitorVoid.java:21)
org.jetbrains.kotlin.psi.KtVisitor.visitClass(KtVisitor.java:33)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitClass(KtVisitorVoid.java:33)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitClass(KtVisitorVoid.java:459)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitClass(KtVisitorVoid.java:21)
org.jetbrains.kotlin.psi.KtClass.accept(KtClass.kt:20)
org.jetbrains.kotlin.psi.KtElementImplStub.accept(KtElementImplStub.java:59)
org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.SharedImplUtil.acceptChildren(SharedImplUtil.java:200)
org.jetbrains.kotlin.com.intellij.psi.impl.source.PsiFileImpl.acceptChildren(PsiFileImpl.java:735)
org.jetbrains.kotlin.psi.KtTreeVisitorVoid.visitElement(KtTreeVisitorVoid.java:25)
org.jetbrains.kotlin.com.intellij.psi.PsiElementVisitor.visitFile(PsiElementVisitor.java:34)
org.jetbrains.kotlin.psi.KtVisitor.visitKtFile(KtVisitor.java:73)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitKtFile(KtVisitorVoid.java:69)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitKtFile(KtVisitorVoid.java:513)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitKtFile(KtVisitorVoid.java:21)
org.jetbrains.kotlin.psi.KtFile.accept(KtFile.kt:242)
org.jetbrains.kotlin.psi.KtFile.accept(KtFile.kt:229)
io.gitlab.arturbosch.detekt.api.BaseRule.visit(BaseRule.kt:53)
io.gitlab.arturbosch.detekt.api.BaseRule.visitFile(BaseRule.kt:43)
io.gitlab.arturbosch.detekt.api.RuleSet.accept(RuleSet.kt:35)
io.gitlab.arturbosch.detekt.core.Detektor.analyze(Detektor.kt:76)
io.gitlab.arturbosch.detekt.core.Detektor.runSync(Detektor.kt:44)
io.gitlab.arturbosch.detekt.core.Detektor.run(Detektor.kt:28)
io.gitlab.arturbosch.detekt.core.DetektFacade.run(DetektFacade.kt:41)
io.gitlab.arturbosch.detekt.cli.runners.Runner.execute(Runner.kt:29)
io.gitlab.arturbosch.detekt.cli.Main.main(Main.kt:16)

MinimalRepro.kt

package com.example

abstract class MinimalRepro {
    var childList = mutableListOf<Any>()

    open fun value(): Any? = null

    override fun equals(other: Any?): Boolean =
        if (other == null || this::class != other::class) {
            false
        } else {
            val otherSameType = other as MinimalRepro
            childList == otherSameType.childList && value() == otherSameType.value()
        }

    override fun hashCode() = childList.hashCode() + 31 * (value()?.hashCode() ?: 0)

}

Detekt Config

potential-bugs:
  active: true
  Deprecation:
    active: true
  DuplicateCaseInWhenExpression:
    active: true
  EqualsAlwaysReturnsTrueOrFalse:
    active: true

Version

From my build.gradle

plugins {
    id 'org.jetbrains.kotlin.multiplatform' version '1.3.60'
    id 'org.jlleitschuh.gradle.ktlint' version '9.1.1'
    id 'io.gitlab.arturbosch.detekt' version '1.2.0'
    id 'org.jetbrains.dokka' version '0.10.0'
}

Expected Behavior

No exception thrown.

Observed Behavior

Exception thrown. See above.

Steps to Reproduce

  • Put the above code snippet in src/commonMain/kotlin/com/example/MinimalRepro.kt
  • Add a build.gradle that loads detekt plugin 1.2.0 (see config snippet above) and that scans src/
  • gradle detekt

Observe stack trace.

Context

Workaround was to change fun equals(...) = ... to fun equals(...) { return ... }

Impact is low.

Your Environment

  • Version of detekt used: 1.2.0
  • Version of Gradle used (if applicable):6.0.1
  • Operating System and version: Linux pop-os 5.3.0-22-generic#24+system76~1573659475~19.10~26b2022-Ubuntu SMP Wed Nov 13 20:0 x86_64 x86_64 x86_64 GNU/Linux
  • Link to your project (if it's a public repository): https://gitlab.com/temper-lang/pattern
@schalkms
Copy link
Member

schalkms commented Dec 5, 2019

Thanks for the detailed bug report! It was really easy to understand and investigate the issue.
Whilst investigating I couldn't reproduce the crash. This has been fixed by #2124 and is part of v1.2.2.

@mikesamuel
Copy link
Author

Sorry, should have upgraded to latest before posting. Thanks for making/maintaining detekt.

@schalkms
Copy link
Member

No worries..
Thanks for the kind words! That's really motivating to read. 😊

@arturbosch arturbosch added this to the 1.3.0 milestone Dec 22, 2019
@lock lock bot locked as resolved and limited conversation to collaborators Apr 2, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants