Skip to content

Metro does not check for clashing property types in contributed graph extensions #904

@timoloewe

Description

@timoloewe

Description

Given a setup that defines a graph extension using @ContributesGraphExtension and multiple contributed interfaces that contain properties with the same name, but different types, like so:

@ContributesGraphExtension(ChildScope::class)
interface ChildGraph {

    @ContributesGraphExtension.Factory(AppScope::class)
    interface Factory {
        fun createChild(): ChildGraph
    }
}

@ContributesTo(ChildScope::class)
interface StringProvider {
    val foo: String

    @Provides
    fun provideString(): String = "test"
}

@ContributesTo(ChildScope::class)
interface IntProvider {
    val foo: Int

    @Provides
    fun provideInt(): Int = 1
}

I expect Metro to fail at compile-time, because the two properties clash. Instead, Metro compiles successfully and the code eventually crashes at runtime when recovering the contributed type:

Exception in thread "main" java.lang.ClassCastException: class java.lang.Integer cannot be cast to class java.lang.String (java.lang.Integer and java.lang.String are in module java.base of loader 'bootstrap')
	at metro.reproducer.AppGraph$$$ContributedChildGraph.getFoo(AppGraph.kt)
	at metro.reproducer.AppGraphKt.main(AppGraph.kt:45)
	at metro.reproducer.AppGraphKt.main(AppGraph.kt)

Self-contained Reproducer

Complete reproducer: metro-reproducer-clashing-properties.zip

Metro version

0.5.5

Context

For "normal" dependency graphs (using @DependencyGraph), this fails at compile-time as expected:

'val foo: Int' defined in 'metro/reproducer/IntProvider' clashes with 'val foo: String' defined in 'metro/reproducer/StringProvider': property types are incompatible.

I think I remember Dagger/Anvil failing at compile-time as well in such scenarios (although I did not verify this right now).

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions