Kotlin 1.7.0 호환성 가이드
Kotlin 1.7.0 호환성 가이드
Keep the Language Modern과 Comfortable Updates는 Kotlin 언어 설계의 기본 원칙 두 가지예요. 전자는 언어 진화를 막는 구조는 제거해야 한다는 뜻이고, 후자는 그런 제거를 미리 잘 알려서 코드 마이그레이션을 최대한 매끄럽게 해야 한다는 뜻이에요.
대부분의 언어 변경은 이미 업데이트 변경 로그나 컴파일러 경고 같은 다른 채널을 통해 안내됐지만, 이 문서는 그 변경들을 한자리에 모아서 Kotlin 1.6에서 1.7로 마이그레이션할 때 참고할 수 있는 완전한 레퍼런스를 제공해요.
본문
기본 용어
이 문서에서는 몇 가지 종류의 호환성을 다뤄요.
- source(소스): 소스 비호환 변경은 예전에는 (경고나 오류 없이) 잘 컴파일되던 코드가 더 이상 컴파일되지 않게 만드는 변경이에요.
- binary(바이너리): 두 바이너리 아티팩트를 서로 바꿔 써도 로딩이나 링크 오류가 나지 않으면 바이너리 호환이라고 불러요.
- behavioral(동작): 같은 프로그램이 변경 적용 전후에 다르게 동작한다면 동작 비호환 변경이라고 해요.
이 정의는 순수 Kotlin에만 해당한다는 점 기억해 두세요. 다른 언어(예를 들어 Java) 관점에서 본 Kotlin 코드의 호환성은 이 문서의 범위 밖이에요.
언어
안전 호출 결과를 항상 nullable로 만들기
Issue: KT-46860
Component: Core language
Incompatible change type: source
Short summary: Kotlin 1.7부터는 안전 호출의 리시버가 non-nullable이어도 안전 호출 결과 타입을 항상 nullable로 취급해요.
Deprecation cycle:
- <1.3: non-nullable 리시버에 대한 불필요한 안전 호출에 대해 경고를 내요.
- 1.6.20: 불필요한 안전 호출의 결과 타입이 다음 버전에서 바뀔 것임을 추가로 경고해요.
- 1.7.0: 안전 호출 결과 타입을 nullable로 바꿔요.
-XXLanguage:-SafeCallsAreAlwaysNullable을 쓰면 1.7 이전 동작으로 임시로 되돌릴 수 있어요.
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: 모든 경우에 오류를 보고해요.
non-public 기본 생성자에 선언된 public 프로퍼티를 통해 non-public 타입 노출 금지
Issue: KT-28078
Component: Core language
Incompatible change type: source
Short summary: Kotlin은 private 기본 생성자에서 non-public 타입을 가진 public 프로퍼티를 선언하지 못하게 해요. 그런 프로퍼티를 다른 패키지에서 접근하면 IllegalAccessError가 발생할 수 있어요.
Deprecation cycle:
- 1.3.20: non-public 타입을 가진, non-public 생성자에 선언된 public 프로퍼티에 대해 경고를 내요.
- 1.6.20: progressive 모드에서 이 경고를 오류로 올려요.
- 1.7.0: 이 경고를 오류로 올려요.
enum 이름으로 한정된 초기화되지 않은 enum 항목 접근 금지
Issue: KT-41124
Component: Core language
Incompatible change type: source
Short summary: Kotlin 1.7부터 enum 정적 초기화 블록에서 enum 이름으로 한정된 초기화되지 않은 enum 항목에 접근할 수 없게 돼요.
Deprecation cycle:
- 1.7.0: enum 정적 초기화 블록에서 초기화되지 않은 enum 항목에 접근하면 오류를 보고해요.
when 조건 분기와 루프 조건에서 복잡한 부울 표현식의 상수 값을 계산하는 것 금지
Issue: KT-39883
Component: Core language
Incompatible change type: source
Short summary: Kotlin은 더 이상 리터럴 true와 false 외의 상수 부울 표현식에 기반한 완전성(exhaustiveness)이나 제어 흐름 가정을 하지 않아요.
Deprecation cycle:
- 1.5.30:
when분기나 루프 조건에서 복잡한 상수 부울 표현식에 기반해when의 완전성이나 제어 흐름 도달 가능성(reachability)이 결정되면 경고를 내요. - 1.7.0: 이 경고를 오류로 올려요.
enum, sealed, Boolean subject를 가진 when 문을 기본적으로 완전하게 만들기
Issue: KT-47709
Component: Core language
Incompatible change type: source
Short summary: Kotlin 1.7은 enum, sealed, Boolean subject를 가진 when 문이 완전하지 않으면 오류를 보고해요.
Deprecation cycle:
- 1.6.0: enum, sealed, Boolean subject를 가진
when문이 완전하지 않으면 경고를 내요(progressive 모드에서는 오류). - 1.7.0: 이 경고를 오류로 올려요.
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: 이 경고를 오류로 올려요.
-
= 1.8: 일부 deprecated 구성은 새 언어 기능에 재사용해요.
타입 nullability 강화 개선
Issue: KT-48623
Component: Kotlin/JVM
Incompatible change type: source
Short summary: Kotlin 1.7은 Java 코드의 타입 nullability 어노테이션을 로드하고 해석하는 방식을 바꿔요.
Deprecation cycle:
- 1.4.30: 더 정밀한 타입 nullability가 오류를 일으킬 수 있는 경우에 대해 경고를 내요.
- 1.7.0: Java 타입의 더 정밀한 nullability를 추론해요.
-XXLanguage:-TypeEnhancementImprovementsInStrictMode을 쓰면 1.7 이전 동작으로 임시로 되돌릴 수 있어요.
서로 다른 숫자 타입 간의 암시적 강제 변환 방지
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 수정 이전 동작으로 임시로 되돌릴 수 있어요. -
= 1.7.20: 다른 영향받는 경우에서 다운캐스트 동작을 수정해요.
컴파일러 옵션 -Xjvm-default의 enable 및 compatibility 모드 deprecated 처리
Issue: KT-46329
Component: Kotlin/JVM
Incompatible change type: source
Short summary: Kotlin 1.6.20은 -Xjvm-default 컴파일러 옵션의 enable 및 compatibility 모드 사용에 대해 경고를 내요.
Deprecation cycle:
- 1.6.20:
-Xjvm-default컴파일러 옵션의enable및compatibility모드에 대해 경고를 내요. -
= 1.8.0: 이 경고를 오류로 올려요.
이름이 suspend인 함수를 trailing lambda와 함께 호출하는 것 금지
Issue: KT-22562
Component: Core language
Incompatible change type: source
Short summary: Kotlin 1.6부터는 단일 인자로 함수 타입을 갖는 suspend라는 이름의 사용자 함수를 trailing lambda로 호출할 수 없게 돼요.
Deprecation cycle:
- 1.3.0: 그런 함수 호출에 대해 경고를 내요.
- 1.6.0: 이 경고를 오류로 올려요.
- 1.7.0: 언어 문법을 변경해서
{앞의suspend가 키워드로 파싱되도록 해요.
기본 클래스가 다른 모듈에 있으면 그 프로퍼티에 대한 스마트 캐스트 금지
Issue: KT-52629
Component: Core language
Incompatible change type: source
Short summary: Kotlin 1.7부터는 상위클래스가 다른 모듈에 있으면 그 프로퍼티에 대한 스마트 캐스트를 허용하지 않아요.
Deprecation cycle:
- 1.6.0: 다른 모듈에 있는 상위클래스에 선언된 프로퍼티에 대한 스마트 캐스트에 대해 경고를 내요.
- 1.7.0: 이 경고를 오류로 올려요.
-XXLanguage:-ProhibitSmartcastsOnPropertyFromAlienBaseClass을 쓰면 1.7 이전 동작으로 임시로 되돌릴 수 있어요.
타입 추론 중 의미 있는 제약 조건을 무시하지 않기
Issue: KT-52668
Component: Core language
Incompatible change type: source
Short summary: Kotlin 1.4−1.6은 잘못된 최적화 때문에 타입 추론 중 일부 타입 제약 조건을 무시했어요. 그 결과 타입이 안전하지 않은 코드를 작성할 수 있었고 런타임에 ClassCastException이 발생할 수 있었어요. Kotlin 1.7은 이 제약 조건들을 고려해서 그런 안전하지 않은 코드를 금지해요.
Deprecation cycle:
- 1.5.20: 모든 타입 추론 제약 조건을 고려하면 타입 불일치가 발생할 표현식에 대해 경고를 내요.
- 1.7.0: 모든 제약 조건을 고려해서 이 경고를 오류로 올려요.
-XXLanguage:-ProperTypeInferenceConstraintsProcessing을 쓰면 1.7 이전 동작으로 임시로 되돌릴 수 있어요.
표준 라이브러리
컬렉션 min/max 함수의 반환 타입을 점진적으로 non-nullable로 변경
Issue: KT-38854
Component: kotlin-stdlib
Incompatible change type: source
Short summary: 컬렉션 min과 max 함수의 반환 타입이 Kotlin 1.7에서 non-nullable로 바뀌어요.
Deprecation cycle:
- 1.4.0: 동의어로
...OrNull함수를 도입하고 영향받는 API를 deprecated 처리해요(자세한 내용은 이슈 참고). - 1.5.0: 영향받는 API의 deprecation 수준을 오류로 올려요.
- 1.6.0: deprecated 함수를 공개 API에서 숨겨요.
- 1.7.0: 영향받는 API를 non-nullable 반환 타입으로 다시 도입해요.
부동소수점 배열 함수 deprecated 처리: contains, indexOf, lastIndexOf
Issue: KT-28753
Component: kotlin-stdlib
Incompatible change type: source
Short summary: Kotlin은 전체 순서(total order) 대신 IEEE-754 순서로 값을 비교하는 부동소수점 배열 함수 contains, indexOf, lastIndexOf를 deprecated 처리해요.
Deprecation cycle:
- 1.4.0: 영향받는 함수를 경고와 함께 deprecated 처리해요.
- 1.6.0: deprecation 수준을 오류로 올려요.
- 1.7.0: deprecated 함수를 공개 API에서 숨겨요.
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: deprecated 함수를 stdlib에서 제거해요.
-
= 1.8: 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.8.0: deprecation 수준을 오류로 올려요.
- 1.9.0: deprecated 함수를 공개 API에서 제거해요.
도구
KotlinGradleSubplugin 클래스 제거
Issue: KT-48831
Component: Gradle
Incompatible change type: source
Short summary: KotlinGradleSubplugin 클래스를 제거해요. 대신 KotlinCompilerPluginSupportPlugin 클래스를 사용해요.
Deprecation cycle:
- 1.6.0: deprecation 수준을 오류로 올려요.
- 1.7.0: deprecated 클래스를 제거해요.
useIR 컴파일러 옵션 제거
Issue: KT-48847
Component: Gradle
Incompatible change type: source
Short summary: deprecated 처리되고 숨겨진 useIR 컴파일러 옵션을 제거해요.
Deprecation cycle:
- 1.5.0: deprecation 수준을 경고로 올려요.
- 1.6.0: 옵션을 숨겨요.
- 1.7.0: deprecated 옵션을 제거해요.
kapt.use.worker.api Gradle 프로퍼티 deprecated 처리
Issue: KT-48826
Component: Gradle
Incompatible change type: source
Short summary: kapt를 Gradle Workers API로 실행할 수 있게 해주던 kapt.use.worker.api 프로퍼티(기본값: true)를 deprecated 처리해요.
Deprecation cycle:
- 1.6.20: deprecation 수준을 경고로 올려요.
-
= 1.8.0: 이 프로퍼티를 제거해요.
kotlin.experimental.coroutines Gradle DSL 옵션과 kotlin.coroutines Gradle 프로퍼티 제거
Issue: KT-50494
Component: Gradle
Incompatible change type: source
Short summary: kotlin.experimental.coroutines Gradle DSL 옵션과 kotlin.coroutines 프로퍼티를 제거해요.
Deprecation cycle:
- 1.6.20: deprecation 수준을 경고로 올려요.
- 1.7.0: DSL 옵션, 그 옵션을 감싸는
experimental블록, 그리고 프로퍼티를 제거해요.
useExperimentalAnnotation 컴파일러 옵션 deprecated 처리
Issue: KT-47763
Component: Gradle
Incompatible change type: source
Short summary: 모듈에서 API를 사용하도록 opt-in하는 데 쓰이던 숨겨진 useExperimentalAnnotation() Gradle 함수를 제거해요. 대신 optIn() 함수를 사용할 수 있어요.
Deprecation cycle:
- 1.6.0: deprecation 옵션을 숨겨요.
- 1.7.0: deprecated 옵션을 제거해요.
kotlin.compiler.execution.strategy 시스템 프로퍼티 deprecated 처리
Issue: KT-51830
Component: Gradle
Incompatible change type: source
Short summary: 컴파일러 실행 전략을 선택하는 데 쓰이던 kotlin.compiler.execution.strategy 시스템 프로퍼티를 deprecated 처리해요. 대신 Gradle 프로퍼티 kotlin.compiler.execution.strategy나 컴파일 태스크 프로퍼티 compilerExecutionStrategy를 사용해요.
Deprecation cycle:
- 1.7.0: deprecation 수준을 경고로 올려요.
-
1.7.0: 프로퍼티를 제거해요.
kotlinOptions.jdkHome 컴파일러 옵션 제거
Issue: KT-46541
Component: Gradle
Incompatible change type: source
Short summary: 기본 JAVA_HOME 대신 지정된 위치의 사용자 JDK를 클래스패스에 포함하는 데 쓰이던 kotlinOptions.jdkHome 컴파일러 옵션을 제거해요. 대신 Java 툴체인을 사용해요.
Deprecation cycle:
- 1.5.30: deprecation 수준을 경고로 올려요.
-
1.7.0: 옵션을 제거해요.
noStdlib 컴파일러 옵션 제거
Issue: KT-49011
Component: Gradle
Incompatible change type: source
Short summary: noStdlib 컴파일러 옵션을 제거해요. Gradle 플러그인은 kotlin.stdlib.default.dependency=true 프로퍼티를 사용해 Kotlin 표준 라이브러리 포함 여부를 제어해요.
Deprecation cycle:
- 1.5.0: deprecation 수준을 경고로 올려요.
- 1.7.0: 옵션을 제거해요.
kotlin2js와 kotlin-dce-plugin 플러그인 제거
Issue: KT-48276
Component: Gradle
Incompatible change type: source
Short summary: kotlin2js와 kotlin-dce-plugin 플러그인을 제거해요. kotlin2js 대신 새 org.jetbrains.kotlin.js 플러그인을 사용해요. 죽은 코드 제거(DCE)는 Kotlin/JS Gradle 플러그인이 제대로 구성되면 동작해요.
Deprecation cycle:
- 1.4.0: deprecation 수준을 경고로 올려요.
- 1.7.0: 플러그인을 제거해요.
컴파일 태스크 변경 사항
Issue: KT-32805
Component: Gradle
Incompatible change type: source
Short summary: Kotlin 컴파일 태스크는 더 이상 Gradle AbstractCompile 태스크를 상속하지 않아요. 그래서 sourceCompatibility와 targetCompatibility 입력을 Kotlin 사용자 스크립트에서 더 이상 쓸 수 없어요. SourceTask.stableSources 입력도 더 이상 쓸 수 없어요. sourceFilesExtensions 입력은 제거됐어요. deprecated 처리된 Gradle destinationDir: File 출력은 destinationDirectory: DirectoryProperty 출력으로 대체됐어요. KotlinCompile 태스크의 classpath 프로퍼티는 deprecated 처리됐어요.
Deprecation cycle:
- 1.7.0: 입력을 쓸 수 없게 되고, 출력이 대체되며,
classpath프로퍼티가 deprecated 처리돼요.