Kotlin 1.9.x 호환성 가이드
Kotlin 1.9.x 호환성 가이드
Keep the Language Modern과 Comfortable Updates는 Kotlin 언어 설계의 기본 원칙 두 가지예요. 전자는 언어 진화를 막는 구조는 제거해야 한다는 뜻이고, 후자는 그런 제거를 미리 잘 알려서 코드 마이그레이션을 최대한 매끄럽게 해야 한다는 뜻이에요.
대부분의 언어 변경은 이미 업데이트 변경 로그나 컴파일러 경고 같은 다른 채널을 통해 안내됐지만, 이 문서는 그 변경들을 한자리에 모아서 Kotlin 1.8에서 1.9로 마이그레이션할 때 참고할 수 있는 완전한 레퍼런스를 제공해요.
본문
기본 용어
이 문서에서는 몇 가지 종류의 호환성을 다뤄요.
- source(소스): 소스 비호환 변경은 예전에는 (경고나 오류 없이) 잘 컴파일되던 코드가 더 이상 컴파일되지 않게 만드는 변경이에요.
- binary(바이너리): 두 바이너리 아티팩트를 서로 바꿔 써도 로딩이나 링크 오류가 나지 않으면 바이너리 호환이라고 불러요.
- behavioral(동작): 같은 프로그램이 변경 적용 전후에 다르게 동작한다면 동작 비호환 변경이라고 해요.
이 정의는 순수 Kotlin에만 해당한다는 점 기억해 두세요. 다른 언어(예를 들어 Java) 관점에서 본 Kotlin 코드의 호환성은 이 문서의 범위 밖이에요.
언어
언어 버전 1.3 제거
Issue: KT-61111
Component: Core language
Incompatible change type: source
Short summary: Kotlin 1.9는 언어 버전 1.9를 도입하고 언어 버전 1.3에 대한 지원을 제거해요.
Deprecation cycle:
- 1.6.0: 경고를 보고해요.
- 1.9.0: 경고를 오류로 올려요.
상위 인터페이스 타입이 함수 리터럴일 때 super 생성자 호출 금지
Issue: KT-46344
Component: Core language
Incompatible change type: source
Short summary: 인터페이스가 함수 리터럴 타입에서 상속받으면 Kotlin 1.9는 그런 생성자가 존재하지 않으므로 super 생성자 호출을 금지해요.
Deprecation cycle:
- 1.7.0: 경고(또는 progressive 모드에서는 오류)를 보고해요.
- 1.9.0: 경고를 오류로 올려요.
어노테이션 파라미터 타입에서 순환 금지
Issue: KT-47932
Component: Core language
Incompatible change type: source
Short summary: Kotlin 1.9는 어노테이션의 타입이 그 파라미터 타입 중 하나로 직접 또는 간접적으로 사용되는 것을 금지해요. 이렇게 해서 순환이 생기지 않게 해요. 다만 파라미터 타입이 그 어노테이션 타입의 Array나 vararg인 것은 허용돼요.
Deprecation cycle:
- 1.7.0: 어노테이션 파라미터 타입의 순환에 대해 경고(또는 progressive 모드에서는 오류)를 보고해요.
- 1.9.0: 경고를 오류로 올려요.
-XXLanguage:-ProhibitCyclesInAnnotations을 쓰면 1.9 이전 동작으로 임시로 되돌릴 수 있어요.
파라미터가 없는 함수 타입에 @ExtensionFunctionType 어노테이션 사용 금지
Issue: KT-43527
Component: Core language
Incompatible change type: source
Short summary: Kotlin 1.9는 파라미터가 없는 함수 타입이나 함수 타입이 아닌 타입에 @ExtensionFunctionType 어노테이션을 쓰는 것을 금지해요.
Deprecation cycle:
- 1.7.0: 함수 타입이 아닌 타입의 어노테이션에 대해 경고를 보고하고, 함수 타입 인 타입의 어노테이션에 대해서는 오류를 보고해요.
- 1.9.0: 함수 타입에 대한 경고를 오류로 올려요.
할당 시 Java 필드 타입 불일치 금지
Issue: KT-48994
Component: Kotlin/JVM
Incompatible change type: source
Short summary: Kotlin 1.9는 Java 필드에 할당되는 값의 타입이 Java 필드의 프로젝션된 타입(projected type)과 일치하지 않는 것을 감지하면 컴파일러 오류를 보고해요.
Deprecation cycle:
- 1.6.0: 프로젝션된 Java 필드 타입이 할당된 값 타입과 일치하지 않으면 경고(또는 progressive 모드에서는 오류)를 보고해요.
- 1.9.0: 경고를 오류로 올려요.
-XXLanguage:-RefineTypeCheckingOnAssignmentsToJavaFields을 쓰면 1.9 이전 동작으로 임시로 되돌릴 수 있어요.
플랫폼 타입 nullability 단언 예외에 소스 코드 발췌 없음
Issue: KT-57570
Component: Kotlin/JVM
Incompatible change type: behavioral
Short summary: Kotlin 1.9에서는 표현식 null 검사의 예외 메시지에 소스 코드 발췌가 포함되지 않아요. 대신 메서드나 필드의 이름이 표시돼요. 표현식이 메서드나 필드가 아니면 메시지에 추가 정보가 제공되지 않아요.
Deprecation cycle:
- < 1.9.0: 표현식 null 검사로 생성된 예외 메시지에 소스 코드 발췌가 포함돼요.
- 1.9.0: 표현식 null 검사로 생성된 예외 메시지에 메서드나 필드 이름만 포함돼요.
-XXLanguage:-NoSourceCodeInNotNullAssertionExceptions을 쓰면 1.9 이전 동작으로 임시로 되돌릴 수 있어요.
super 호출을 추상 상위클래스 멤버에 위임하는 것 금지
Issues: KT-45508, KT-49017, KT-38078
Component: Core language
Incompatible change type: source
Short summary: Kotlin은 명시적이거나 암시적인 super 호출이 상위클래스의 추상 멤버에 위임되면, 상위 인터페이스에 기본 구현이 있더라도 컴파일 오류를 보고해요.
Deprecation cycle:
- 1.5.20: 모든 추상 멤버를 오버라이드하지 않는 비추상 클래스가 사용될 때 경고를 내요.
- 1.7.0: super 호출이 실제로 상위클래스의 추상 멤버에 접근하면 경고를 보고해요.
- 1.7.0:
-Xjvm-default=all또는-Xjvm-default=all-compatibility호환 모드가 활성화되면 영향받는 모든 경우에 오류를 보고하고, progressive 모드에서도 오류를 보고해요. - 1.8.0: 상위클래스의 오버라이드되지 않은 추상 메서드로 구체 클래스를 선언하는 경우와,
Any의 메서드에 대한 super 호출이 상위클래스에서 추상으로 오버라이드된 경우에 오류를 보고해요. - 1.9.0: 상위클래스의 추상 메서드에 대한 명시적 super 호출을 포함해 영향받는 모든 경우에 오류를 보고해요.
when-with-subject의 혼란스러운 문법 deprecated 처리
Issue: KT-48385
Component: Core language
Incompatible change type: source
Short summary: Kotlin 1.6에서 when 조건식의 헷갈리기 쉬운 몇 가지 문법 구성을 deprecated 처리했어요.
Deprecation cycle:
- 1.6.20: 영향받는 표현식에 deprecation 경고를 내요.
- 1.8.0: 이 경고를 오류로 올려요.
-XXLanguage:-ProhibitConfusingSyntaxInWhenBranches을 쓰면 1.8 이전 동작으로 임시로 되돌릴 수 있어요. -
= 2.1: 일부 deprecated 구성은 새 언어 기능에 재사용해요.
서로 다른 숫자 타입 간의 암시적 강제 변환 방지
Issue: KT-48645
Component: Kotlin/JVM
Incompatible change type: behavioral
Short summary: Kotlin은 의미상 그 타입으로의 다운캐스트만 필요했던 곳에서 숫자 값을 원시 숫자 타입으로 자동 변환하는 것을 피해요.
Deprecation cycle:
- < 1.5.30: 모든 영향받는 경우에서 예전 동작.
- 1.5.30: 생성된 프로퍼티 위임 접근자에서 다운캐스트 동작을 수정해요.
-Xuse-old-backend을 쓰면 1.5.30 수정 이전 동작으로 임시로 되돌릴 수 있어요. -
= 2.0: 다른 영향받는 경우에서 다운캐스트 동작을 수정해요.
제네릭 타입 별칭 사용에서 상한 위반 금지 (별칭 타입의 타입 인자에 제네릭 타입 인자로 타입 파라미터가 사용되는 경우)
Issue: KT-54066
Component: Core language
Incompatible change type: source
Short summary: Kotlin은 별칭 타입의 타입 인자에 제네릭 타입 인자로 typealias 타입 파라미터가 사용되는 경우(예: typealias Alias<T> = Base<List<T>>)에, 별칭 타입의 해당 타입 파라미터의 상한 제약을 위반하는 타입 인자를 가진 타입 별칭 사용을 금지해요.
Deprecation cycle:
- 1.8.0: 제네릭 typealias 사용이 별칭 타입의 해당 타입 파라미터의 상한 제약을 위반하는 타입 인자를 가지면 경고를 보고해요.
- 2.0.0: 경고를 오류로 올려요.
공개 시그니처에서 로컬 타입을 근사할 때 nullability 유지
Issue: KT-53982
Component: Core language
Incompatible change type: source, binary
Short summary: 반환 타입을 명시하지 않은 식 본문 함수에서 로컬 또는 익명 타입이 반환되면, Kotlin 컴파일러는 그 타입의 알려진 상위 타입을 사용해 반환 타입을 추론(또는 근사)해요. 이 과정에서 컴파일러가 실제로 null 값이 반환될 수 있는데 non-nullable 타입을 추론할 수 있었어요.
Deprecation cycle:
- 1.8.0: flexible 타입을 flexible 상위 타입으로 근사해요.
- 1.8.0: 선언이 nullable이어야 하는데 non-nullable 타입으로 추론되면 경고를 보고하고, 타입을 명시적으로 지정하도록 안내해요.
- 2.0.0: nullable 타입을 nullable 상위 타입으로 근사해요.
-XXLanguage:-KeepNullabilityWhenApproximatingLocalType을 쓰면 2.0 이전 동작으로 임시로 되돌릴 수 있어요.
오버라이드를 통해 deprecation 전파하지 않기
Issue: KT-47902
Component: Core language
Incompatible change type: source
Short summary: Kotlin 1.9부터는 상위클래스의 deprecated 멤버의 deprecation이 하위클래스의 그 오버라이드 멤버로 더 이상 전파되지 않아요. 이를 통해 상위클래스 멤버는 deprecated로 만들면서 하위클래스에서는 deprecated로 남겨 두지 않는 명시적 메커니즘을 제공해요.
Deprecation cycle:
- 1.6.20: 향후 동작 변경 메시지와 함께, 이 경고를 억제하거나 deprecated 멤버의 오버라이드에
@Deprecated어노테이션을 명시적으로 추가하라는 안내와 함께 경고를 보고해요. - 1.9.0: 오버라이드된 멤버로 deprecation 상태를 전파하는 것을 중단해요. 이 변경은 progressive 모드에서 즉시 적용되기도 해요.
어노테이션 클래스에서 파라미터 선언 외의 위치에 컬렉션 리터럴 사용 금지
Issue: KT-39041
Component: Core language
Incompatible change type: source
Short summary: Kotlin은 컬렉션 리터럴을 제한된 방식으로 사용할 수 있어요. 즉 어노테이션 클래스의 파라미터에 배열을 전달하거나 그 파라미터의 기본값을 지정하는 데 쓸 수 있어요. 하지만 그 외에도 Kotlin은 어노테이션 클래스 안의 다른 곳(예: 중첩 객체)에서 컬렉션 리터럴을 허용했어요. Kotlin 1.9는 어노테이션 클래스에서 파라미터의 기본값 외의 위치에 컬렉션 리터럴을 쓰는 것을 금지해요.
Deprecation cycle:
- 1.7.0: 어노테이션 클래스의 중첩 객체에서 배열 리터럴을 사용하면 경고(또는 progressive 모드에서는 오류)를 보고해요.
- 1.9.0: 경고를 오류로 올려요.
기본값 식에서 파라미터의 앞방향 참조 금지
Issue: KT-25694
Component: Core language
Incompatible change type: source
Short summary: Kotlin 1.9는 다른 파라미터의 기본값 식에서 파라미터를 앞방향으로 참조하는 것을 금지해요. 이렇게 하면 파라미터가 기본값 식에서 접근될 때쯤에는 그 파라미터에 함수로 전달된 값이나 자기 자신의 기본값 식으로 초기화된 값이 이미 있을 거라는 점이 보장돼요.
Deprecation cycle:
- 1.7.0: 기본값을 가진 파라미터가 그보다 앞에 오는 다른 파라미터의 기본값에서 참조되면 경고(또는 progressive 모드에서는 오류)를 보고해요.
- 1.9.0: 경고를 오류로 올려요.
-XXLanguage:-ProhibitIllegalValueParameterUsageInDefaultArguments을 쓰면 1.9 이전 동작으로 임시로 되돌릴 수 있어요.
inline 함수형 파라미터에 대한 확장 호출 금지
Issue: KT-52502
Component: Core language
Incompatible change type: source
Short summary: Kotlin은 inline 함수형 파라미터를 리시버로 다른 inline 함수에 전달하는 것을 허용했지만, 그런 코드를 컴파일하면 항상 컴파일러 예외가 발생했어요. Kotlin 1.9는 이것을 금지해서 컴파일러가 중단되는 대신 오류를 보고하게 해요.
Deprecation cycle:
- 1.7.20: inline 함수형 파라미터에 대한 inline 확장 호출에 대해 경고(또는 progressive 모드에서는 오류)를 보고해요.
- 1.9.0: 경고를 오류로 올려요.
이름이 suspend인 infix 함수를 익명 함수 인자와 함께 호출하는 것 금지
Issue: KT-49264
Component: Core language
Incompatible change type: source
Short summary: Kotlin 1.9부터는 단일 인자로 함수 타입을 갖는 suspend라는 이름의 infix 함수를 익명 함수 리터럴로 전달해 호출할 수 없게 돼요.
Deprecation cycle:
- 1.7.20: 익명 함수 리터럴과 함께 쓰이는 suspend infix 호출에 대해 경고를 보고해요.
- 1.9.0: 경고를 오류로 올려요.
-XXLanguage:-ModifierNonBuiltinSuspendFunError을 쓰면 1.9 이전 동작으로 임시로 되돌릴 수 있어요. - TODO: 파서가
suspend fun토큰 시퀀스를 해석하는 방식을 변경해요.
내부 클래스에서 캡처된 타입 파라미터를 가변성에 반하게 사용하는 것 금지
Issue: KT-50947
Component: Core language
Incompatible change type: source
Short summary: Kotlin 1.9는 in 또는 out 가변성을 가진 외부 클래스의 타입 파라미터를 그 클래스의 내부 클래스에서 그 타입 파라미터의 선언된 가변성을 위반하는 위치에 사용하는 것을 금지해요.
Deprecation cycle:
- 1.7.0: 외부 클래스의 타입 파라미터 사용 위치가 그 파라미터의 가변성 규칙을 위반하면 경고(또는 progressive 모드에서는 오류)를 보고해요.
- 1.9.0: 경고를 오류로 올려요.
-XXLanguage:-ReportTypeVarianceConflictOnQualifierArguments을 쓰면 1.9 이전 동작으로 임시로 되돌릴 수 있어요.
복합 할당 연산자에서 명시적 반환 타입이 없는 함수의 재귀 호출 금지
Issue: KT-48546
Component: Core language
Incompatible change type: source
Short summary: Kotlin 1.9는 함수 본문 안의 복합 할당 연산자 인자에서 명시적 반환 타입이 지정되지 않은 함수를 호출하는 것을, 그 함수 본문 안의 다른 표현식에서 현재 금지하는 것과 같은 방식으로 금지해요.
Deprecation cycle:
- 1.7.0: 명시적 반환 타입이 없는 함수가 그 함수 본문 안의 복합 할당 연산자 인자에서 재귀 호출되면 경고(또는 progressive 모드에서는 오류)를 보고해요.
- 1.9.0: 경고를 오류로 올려요.
@NotNull T가 예상되는 곳에 nullable 바운드의 Kotlin 제네릭 파라미터를 넘기는 안전하지 않은 호출 금지
Issue: KT-36770
Component: Kotlin/JVM
Incompatible change type: source
Short summary: Kotlin 1.9는 Java 메서드의 @NotNull으로 주석이 달린 파라미터에 잠재적으로 nullable인 제네릭 타입 값을 전달하는 메서드 호출을 금지해요.
Deprecation cycle:
- 1.5.20: non-nullable 타입이 예상되는 곳에 제약이 없는 제네릭 타입 파라미터가 전달되면 경고를 보고해요.
- 1.9.0: 위 경고 대신 타입 불일치 오류를 보고해요.
-XXLanguage:-ProhibitUsingNullableTypeParameterAgainstNotNullAnnotated을 쓰면 1.8 이전 동작으로 임시로 되돌릴 수 있어요.
enum 클래스의 entry 초기화에서 그 enum의 companion 멤버 접근 금지
Issue: KT-49110
Component: Core language
Incompatible change type: source
Short summary: Kotlin 1.9는 enum entry 초기화에서 enum의 companion 객체에 대한 모든 종류의 접근을 금지해요.
Deprecation cycle:
- 1.6.20: 그런 companion 멤버 접근에 대해 경고(또는 progressive 모드에서는 오류)를 보고해요.
- 1.9.0: 경고를 오류로 올려요.
-XXLanguage:-ProhibitAccessToEnumCompanionMembersInEnumConstructorCall을 쓰면 1.8 이전 동작으로 임시로 되돌릴 수 있어요.
Enum.declaringClass 합성 프로퍼티 deprecated 처리 및 제거
Issue: KT-49653
Component: Kotlin/JVM
Incompatible change type: source
Short summary: Kotlin은 기본 Java 클래스 java.lang.Enum의 getDeclaringClass() 메서드에서 만들어진 Enum 값에 합성 프로퍼티 declaringClass를 사용하는 것을 허용했는데, 이 메서드는 Kotlin Enum 타입에는 없어요. Kotlin 1.9는 이 프로퍼티 사용을 금지하고 확장 프로퍼티 declaringJavaClass로 마이그레이션할 것을 제안해요.
Deprecation cycle:
- 1.7.0:
declaringClass프로퍼티 사용에 대해 경고(또는 progressive 모드에서는 오류)를 보고하고declaringJavaClass확장으로의 마이그레이션을 제안해요. - 1.9.0: 경고를 오류로 올려요.
-XXLanguage:-ProhibitEnumDeclaringClass을 쓰면 1.9 이전 동작으로 임시로 되돌릴 수 있어요. - 2.0.0:
declaringClass합성 프로퍼티를 제거해요.
컴파일러 옵션 -Xjvm-default의 enable 및 compatibility 모드 deprecated 처리
Component: Kotlin/JVM
Incompatible change type: source
Short summary: Kotlin 1.9는 -Xjvm-default 컴파일러 옵션의 enable 및 compatibility 모드 사용을 금지해요.
Deprecation cycle:
- 1.6.20:
-Xjvm-default컴파일러 옵션의enable및compatibility모드에 대해 경고를 내요. - 1.9.0: 이 경고를 오류로 올려요.
빌더 추론 맥락에서 타입 변수를 상한으로 암시적으로 추론하는 것 금지
Issue: KT-47986
Component: Core language
Incompatible change type: source
Short summary: Kotlin 2.0은 빌더 추론 람다 함수 범위에서 사용 지점 타입 정보가 없을 때 타입 변수를 해당 타입 파라미터의 상한으로 추론하는 것을 다른 맥락에서 현재 금지하는 것과 같은 방식으로 금지해요.
Deprecation cycle:
- 1.7.20: 사용 지점 타입 정보가 없는데 타입 파라미터가 선언된 상한으로 추론되면 경고(또는 progressive 모드에서는 오류)를 보고해요.
- 2.0.0: 경고를 오류로 올려요.
표준 라이브러리
Range/Progression이 Collection을 구현하기 시작할 때 잠재적 오버로드 해석 변경에 대해 경고
Issue: KT-49276
Component: Core language / kotlin-stdlib
Incompatible change type: source
Short summary: Kotlin 1.9에서 표준 progression과 그로부터 상속된 구체적인 range들이 Collection 인터페이스를 구현할 계획이에요. 어떤 메서드에 요소를 받는 오버로드와 컬렉션을 받는 오버로드 두 가지가 있다면, 이로 인해 오버로드 해석에서 다른 오버로드가 선택될 수 있어요. Kotlin은 그런 오버로드된 메서드가 range 또는 progression 인자로 호출될 때 경고나 오류를 보고해 이 상황을 눈에 보이게 만들 거예요.
Deprecation cycle:
- 1.6.20: 표준 progression이나 그 range 상속자가 인자로 전달된 오버로드된 메서드가 호출될 때, 이 progression/range가
Collection인터페이스를 구현하면 향후 이 호출에서 다른 오버로드가 선택될 것이라면 경고를 보고해요. - 1.8.0: 이 경고를 오류로 올려요.
- 2.1.0: 오류 보고를 중단하고, progression에서
Collection인터페이스를 구현해서 영향받는 경우에 오버로드 해석 결과를 변경해요.
kotlin.dom과 kotlin.browser 패키지의 선언을 kotlinx.*로 마이그레이션
Issue: KT-39330
Component: kotlin-stdlib (JS)
Incompatible change type: source
Short summary: kotlin.dom과 kotlin.browser 패키지의 선언이 stdlib에서 분리될 준비로 대응하는 kotlinx.* 패키지로 이동돼요.
Deprecation cycle:
- 1.4.0:
kotlinx.dom과kotlinx.browser패키지에 대체 API를 도입해요. - 1.4.0:
kotlin.dom과kotlin.browser패키지의 API를 deprecated 처리하고 위 새 API를 대체 방안으로 제안해요. - 1.6.0: deprecation 수준을 오류로 올려요.
- 1.8.20: JS-IR 타깃에 대해 stdlib에서 deprecated 함수를 제거해요.
-
= 2.0: kotlinx.* 패키지의 API를 별도 라이브러리로 옮겨요.
일부 JS 전용 API deprecated 처리
Issue: KT-48587
Component: kotlin-stdlib (JS)
Incompatible change type: source
Short summary: stdlib의 여러 JS 전용 함수가 제거를 목적으로 deprecated 처리돼요. 여기에는 String.concat(String), String.match(regex: String), String.matches(regex: String), 그리고 비교 함수를 받는 배열의 sort 함수(예: Array<out T>.sort(comparison: (a: T, b: T) -> Int))가 포함돼요.
Deprecation cycle:
- 1.6.0: 영향받는 함수를 경고와 함께 deprecated 처리해요.
- 1.9.0: deprecation 수준을 오류로 올려요.
-
=2.0: deprecated 함수를 공개 API에서 제거해요.
도구
Gradle 설정에서 enableEndorsedLibs 플래그 제거
Issue: KT-54098
Component: Gradle
Incompatible change type: source
Short summary: enableEndorsedLibs 플래그가 Gradle 설정에서 더 이상 지원되지 않아요.
Deprecation cycle:
- < 1.9.0:
enableEndorsedLibs플래그가 Gradle 설정에서 지원돼요. - 1.9.0:
enableEndorsedLibs플래그가 Gradle 설정에서 지원되지 않아요.
Gradle 컨벤션 제거
Issue: KT-52976
Component: Gradle
Incompatible change type: source
Short summary: Gradle 컨벤션은 Gradle 7.1에서 deprecated 처리됐고 Gradle 8에서 제거됐어요.
Deprecation cycle:
- 1.7.20: Gradle 컨벤션 deprecated.
- 1.9.0: Gradle 컨벤션 제거.
KotlinCompile 태스크의 classpath 프로퍼티 제거
Issue: KT-53748
Component: Gradle
Incompatible change type: source
Short summary: KotlinCompile 태스크의 classpath 프로퍼티가 제거돼요.
Deprecation cycle:
- 1.7.0:
classpath프로퍼티가 deprecated 처리돼요. - 1.8.0: deprecation 수준을 오류로 올려요.
- 1.9.0: deprecated 함수를 공개 API에서 제거해요.
kotlin.internal.single.build.metrics.file 프로퍼티 deprecated 처리
Issue: KT-53357
Component: Gradle
Incompatible change type: source
Short summary: 빌드 리포트용 단일 파일을 지정하는 데 쓰이던 kotlin.internal.single.build.metrics.file 프로퍼티를 deprecated 처리해요. kotlin.build.report.single_file 프로퍼티를 kotlin.build.report.output=single_file과 함께 사용해요.
Deprecation cycle:
- 1.8.0: deprecation 수준을 경고로 올려요.
-
= 1.9: 프로퍼티를 삭제해요.