Where upper bound with inheritance or class delegation

I would like to write something like this:

class SectionListImpl<T, C : Any>(
    private val section: SectionList<T, C>,
    private val caps: Array<out C>?
) where T : OptionList<T>, T : Enum<T> : SectionList<T, C> by section {
...

But I can’t compile this when there is both the upper bound where clause and class inheritance at the same time. When I remove one, it will work, but I need both. Is there a way to do this or this is language syntax limitation?

Do you mean this?

) : SectionList<T, C> by section where T : OptionList<T>, T : Enum<T> {

Tried that, it doesn’t compile either.

Ahh, you are right. Somehow, the compiler doesn’t allow where after delegation. Seems like a bug in the compiler, language syntax or something (?). I was able to cheat by introducing another type, so the delegated type is not the last supertype in the list:

class MyList<T>(
    private val list: List<T>
) : List<T> by list, Dummy where T : String

interface Dummy
2 Likes

Witty, I think I will use that for now. Thanks.

I believe the problem is that after by we allow not only a single identifier, but any Kotlin expression. And expressions are allowed to have spaces to support infix functions. In other words, it is interpreted as:

 : SectionList<T, C> by section.where(T)

and it obviously fails.

So we miss a way to end the current expression. Comma is one way to do this, however, after it the compiler expects another type and it doesn’t allow where.

3 Likes

Putting where on a newline works too:

interface I1
interface I2

class MyList<T>(
    private val list: List<T>
) : List<T> by list
        where T : I1, T : I2 {
    /*...*/
}
1 Like

Yeah I think this is might be a bug?

On "classDeclaration: " in keywords and operators:

[modifiers]
('class' | (['fun' {NL}] 'interface'))
{NL}
simpleIdentifier
[{NL} typeParameters]
[{NL} primaryConstructor]
[{NL} ':' {NL} delegationSpecifiers]
[{NL} typeConstraints]
[({NL} classBody) | ({NL} enumClassBody)]

New line character is not compulsory after delegationSpecifiers and before typeConstraints