Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dagger2 @Binds methods' parameter type must be assignable to the return type with interface and implementation

I have a class that implements the interface java.util.function.Function that I'd like to inject for use in another class using Dagger2:

class MyUsefulClass @Inject constructor() : Function<List<String>, String> {

    override fun apply(lines: List<String>): String {
        // Do stuff 
        return ""
    }
}

Usually, I'd declare an @Binds declaration in the module class like so:

@Module
interface MyModule {

    @Binds
    fun provideMyUsefulClass(concretion: MyUsefulClass): Function<List<String>, String>
}

This approach has served me well for all the other classes I have in my project that implement this interface but in this one instance, I'm greeted by the error message:

@Binds methods' parameter type must be assignable to the return type…

What's funny is that changing the return type of the class and the @Binds declaration to Function<MutableList<String>, String> from Function<List<String>, String> works and everything compiles fine.

What am I missing here? The error message is clearly untrue. Is there some massive gotcha I'm unaware of here?

like image 961
HBG Avatar asked Feb 20 '20 12:02

HBG


1 Answers

I suspect this might be a case of "missing" @JvmSuppressWildcards, whereby kotlin adds some ? extends String in the List type and that makes the dagger compiler fail (the error message should contain some more hints).

I guess you need to change your function type to Function<List<@JvmSuppressWildcards String>, String> where you use it.

It's a known annoyance, you can read something more in detail here: https://medium.com/@naturalwarren/dagger-kotlin-3b03c8dd6e9b

I suspect that MutableList doesn't have that problem because you can both 'read' and 'write' strings with it.

like image 145
al3c Avatar answered Oct 08 '22 09:10

al3c