Почему нельзя вводить параметр в Kotlin какие-либо другие границы, если он ограничен другим параметром типа?

Вот минимальный демонстрационный код, который показывает эту проблему:

interface A fun <T1, T2> test() where T2 : T1, T2 : A {} 

Когда я пытаюсь скомпилировать его, компилятор будет жаловаться:

Ошибка: (81, 25) Kotlin: параметр типа не может иметь никаких других границ, если он ограничен другим параметром типа

Я прочитал спецификацию языка Kotlin , но могу найти только следующее ограничение:

Параметр типа не может указывать себя как свою собственную привязку, а несколько параметров типа не могут указывать друг на друга как привязку циклическим образом.

Он не объясняет, какое ограничение я встречаю.

Я изучаю проблему отслеживания ошибок Kotlin, и я нахожу проблему об этом ограничении: Позвольте наследовать параметр типа из другого параметра типа и класса: KT-13768 . Однако этот вопрос был отклонен по следующей причине (обновление от 6 мая 2017 года: этот вопрос был вновь открыт Станиславом Ерохиным):

Я не думаю, что мы сможем правильно скомпилировать код JVM, если удалим это ограничение.

Андрей Бреслав

Поэтому возникает вопрос: почему мы не можем правильно скомпилировать код JVM, если мы удалим это ограничение?

Эта же демонстрация работает в Scala:

 trait A def test[T1, T2 <: T1 with A](): Unit = {} 

Это означает, что Scala может правильно скомпилировать код для JVM. Почему Котлин не может? Является ли это ограничением для гарантирования разрешимого подтипирования в Kotlin (я думаю, что подтипирование является неразрешимым для Scala (у Scala есть система Turing-complete type). Kotlin может хотеть разрешимый подтипирование, как C #.)?

Обновление после ответа от @erokhins ( https://stackoverflow.com/a/43807444/7964561 ):

Есть некоторые тонкие проблемы при поддержке чего-то, запрещенного Java, но разрешенного JVM, особенно в Java-совместимости. Я нахожу интересную проблему при перекодировании в байт-код, созданный с помощью скаляса. Я изменяю код Scala в демо:

 trait A trait B def test[T1 <: B, T2 <: T1 with A](t1: T1, t2: T2): Unit = {} class AB extends A with B 

Scalac будет генерировать следующую подпись:

 // signature <T1::LB;T2:TT1;:LA;>(TT1;TT2;)V // descriptor: (LB;LB;)V public <T1 extends B, T2 extends T1 & A> void test(T1, T2); 

Invoke test with test(new AB, new AB) в Scala будет успешным, так как Scalas вызывает подпись (LB;LB;)V ; но вызывать с test(new AB(), new AB()); в Java не удастся, так как Java вызывает подпись (LB;Ljava/lang/Object;)V , вызывая java.lang.NoSuchMethodError во время выполнения. Это означает, что генерируется скаляр, что-то не может быть вызвано на Java после ослабления этого ограничения. Котлин может встретить ту же проблему после расслабления.

Solutions Collecting From Web of "Почему нельзя вводить параметр в Kotlin какие-либо другие границы, если он ограничен другим параметром типа?"

Эти ограничения были сделаны потому, что у java (language) есть:

  interface A {} // Error:(7, 26) java: a type variable may not be followed by other bounds <T1, T2 extends T1 & A> void test() {} 

И мы полагаем, что это запрещено и на уровне байт-кода. Я копаю в него и кажется, что это разрешено, а scalac генерирует следующую подпись:

  // access flags 0x1 // signature <T1:Ljava/lang/Object;T2:TT1;:LA;>()V // declaration: void test<T1, T2T1 extends A>() public test()V 

Таким образом, мы, вероятно, можем поддержать такие случаи в будущих версиях kotlin.

PS Насколько я знаю, у Котлина есть разрешимый подтипирование, и это не влияет на разрешимость.