question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Kotlin @Binds error with covariant type parameter

See original GitHub issue

Given the interface:

interface Example<T>

The implementation:

class ExampleImpl: Example<List<String>>

The module:

@Module
interface ExampleModule {
    @Binds
    fun provideExample(example: ExampleImpl): Example<List<String>>
}

The error @Binds methods must have only one parameter whose type is assignable to the return type is thrown at compile-time.

Important notes

  1. it happens only with @Binds and not with @Provides So, this works:
@Module
class ExampleModule {
    @Provides
    fun provideExample(example: ExampleImpl): Example<List<String>> = example
}
  1. it happens only when T is used as a covariant type parameter in the implementation of Example. So, this works:
class ExampleImpl: Example<MutableList<String>>

@Module
interface ExampleModule {
    @Binds
    fun provideExample(example: ExampleImpl): Example<MutableList<String>>
}

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Reactions:2
  • Comments:8

github_iconTop GitHub Comments

9reactions
fondesacommented, Apr 16, 2018

My last try was the right one, simply I forgot the @Inject annotation on the constructor of ExampleImpl. The following summary is for people who encounter the same problem. Thanks for your help, considering that now it works, I close the issue, feel free to re-open it if needed.

Short summary

Interface

interface Example<T>

Implementation

class ExampleImpl @Inject constructor() : Example<List<@JvmSuppressWildcards String>>

Module

@Module
interface ExampleModule {
    @Binds
    fun provideExample(example: ExampleImpl): Example<List<String>>
}

Consumer

class Consumer @Inject constructor(private val example: @JvmSuppressWildcards Example<List<String>>)
1reaction
fondesacommented, Apr 16, 2018

I tried with @JvmSuppressWildcards but it doesn’t help in this case. It’s still needed using the @Provides annotation.

Example:

@Module
class ExampleModule {
    @Provides
    fun provideExample(example: ExampleImpl): Example<List<String>> = example
}

class Consumer @Inject constructor(private val example: @JvmSuppressWildcards Example<List<String>>)
Read more comments on GitHub >

github_iconTop Results From Across the Web

Force type parameter to be invariant at use-site when it is ...
Coding example for the question Force type parameter to be invariant at use-site when it is covariant at declaration site-kotlin.
Read more >
Kotlin Generics: Trouble migrating from Java - Stack Overflow
You can solve it adding a new type parameter which other languages ... and the other type parameter as covariant types (using out...
Read more >
Generics: in, out, where | Kotlin
The general rule is this: when a type parameter T of a class C is declared out , it may occur only in...
Read more >
Dagger2 covariant Set multibinding - Google Groups
As context: I found this while prototyping Dagger2 with Kotlin, ... error: @Binds methods must return a primitive, an array, a type variable,...
Read more >
Dependency Injection using the Typeclassless technique
The function multiplyBy2 , as defined above, receives FT: Functor<F> as a parameter. We need to bind FT to this to be able...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found