Repository: evant/kotlin-inject
Pull request #111 (2021-04-15 18:31:54)

Compare nullable & non-nullable types as different on kapt
This fixes the most egregious issue with #110


Patch:
diff --git a/kotlin-inject-compiler-kapt/src/main/kotlin/me/tatarka/inject/compiler/kapt/Util.kt b/kotlin-inject-compiler-kapt/src/main/kotlin/me/tatarka/inject/compiler/kapt/Util.kt
index 63aa9ab..87b879b 100644
--- a/kotlin-inject-compiler-kapt/src/main/kotlin/me/tatarka/inject/compiler/kapt/Util.kt
+++ b/kotlin-inject-compiler-kapt/src/main/kotlin/me/tatarka/inject/compiler/kapt/Util.kt
@@ -246,8 +246,8 @@ fun KmType.isFunction(): Boolean {
 
 private fun KmType.isSuspendFunction(): Boolean {
     return isFunction() &&
-        arguments.size >= 2 &&
-        arguments[arguments.size - 2].type?.classifier?.name == "kotlin/coroutines/Continuation"
+            arguments.size >= 2 &&
+            arguments[arguments.size - 2].type?.classifier?.name == "kotlin/coroutines/Continuation"
 }
 
 fun AnnotationMirror.eqv(other: AnnotationMirror): Boolean {
@@ -277,10 +277,11 @@ fun KmType.eqv(other: KmType): Boolean {
         }
     }
     return classifier == other.classifier &&
-        arguments.eqvItr(other.arguments) { a, b ->
-            a.variance == b.variance &&
-                a.type.eqv(b.type, KmType::eqv)
-        }
+            isNullable() == other.isNullable() &&
+            arguments.eqvItr(other.arguments) { a, b ->
+                a.variance == b.variance &&
+                        a.type.eqv(b.type, KmType::eqv)
+            }
 }
 
 fun KmType.eqvHashCode(collector: HashCollector = HashCollector()): Int {
@@ -325,3 +326,5 @@ inline fun KmProperty.isPrivate() = Flag.Common.IS_PRIVATE(flags)
 inline fun KmConstructor.isPrimary() = Flag.Constructor.IS_PRIMARY(flags)
 
 inline fun KmValueParameter.hasDefault() = Flag.ValueParameter.DECLARES_DEFAULT_VALUE(flags)
+
+inline fun KmType.isNullable() = Flag.Type.IS_NULLABLE(flags)
\ No newline at end of file


Test patch:
diff --git a/compiler-tests/src/test/kotlin/me/tatarka/inject/test/FailureTest.kt b/compiler-tests/src/test/kotlin/me/tatarka/inject/test/FailureTest.kt
index be0b1d1..ae2088f 100644
--- a/compiler-tests/src/test/kotlin/me/tatarka/inject/test/FailureTest.kt
+++ b/compiler-tests/src/test/kotlin/me/tatarka/inject/test/FailureTest.kt
@@ -379,6 +379,28 @@ class FailureTest(private val target: Target) {
             contains("as scope: MyScope2 is already applied")
         }
     }
+
+    @Test
+    fun fails_with_missing_binding_with_nullable_provides_and_non_nullable_usage() {
+        assertThat {
+            projectCompiler.source(
+                "MyComponent.kt",
+                """
+               import me.tatarka.inject.annotations.Component
+               import me.tatarka.inject.annotations.Provides
+               
+               @Component abstract class MyComponent() {
+                 abstract val foo: String
+                 @Provides fun provideFoo(): String? = "foo"
+               }
+                """.trimIndent()
+            ).compile()
+        }.isFailure().output().all {
+            contains(
+                "Cannot find an @Inject constructor or provider for: String"
+            )
+        }
+    }
 }
 
 private fun Target.sourceExt() = when (this) {