Rust, 2년 넘게 미뤄진 never 타입 ! 안정화와 2024 에디션 추론 변경
- Rust는 8월 24일 PR #155499로 never 타입
!을 안정화했으며, 작업에는 2년 이상 걸렸고 이전 에디션 코드에 미치는 작은 호환성 변경을 검토해야 했음 FromStr구현에서 오류 타입을!로 지정하면Result<Self, !>의 오류 분기는 발생할 수 없으므로, 컴파일러가 검사와 처리 코드를 제거해 사실상Self반환과 같은 코드로 최적화함- 무한 루프처럼 값을 만들지 않는 식은
!타입을 가지며 어떤 타입으로도 강제 변환됨. 도달 불가능한 경로라는 사실을 타입 시스템이 이용해 코드와 타입 추론을 단순화함 - 반환형을 쓰지 않은 지역 클로저가 무한 루프만 수행한 뒤
?연산자에 쓰이면 구체 타입을 추론할 정보가 부족해짐. 반환형 주석으로 해결할 수 있지만 실제 값이 없는 함수에 가짜 타입을 적어야 하는 문제가 있었음 - 2024 에디션에서는 이런 never fallback 상황에서 컴파일러가
T를!로 추론함.!가 구현하지 않은Default같은 트레이트를 요구하던 기존 코드는 컴파일 오류가 날 수 있음
Hacker News opinions
never 타입은 절대 일어나지 않는 분기나 호출자에게 제어가 돌아오지 않는 함수를 나타내기에 여러 언어에서 유용하다고 봄. TypeScript에서도 const forever = (): never => { while (true) {} }처럼 씀.
!가 모든 타입으로 강제 변환된다면, 왜 모든 트레이트도 구현한 것처럼 취급하지 않는지 궁금함. 2024 에디션에서는 T를 !로 추론해서 Default 미구현 컴파일 오류가 난다던데.
Default는 실제로 그 타입 값을 만들어내는 함수임. ! 값은 만들 수 없으니 구현하려면 panic이나 무한 루프가 필요하고, 그러면 컴파일 오류를 런타임 오류로 바꾸게 됨.
Waffle이 올해 RustWeek에서 한 "When is never?" 발표도 관련 내용을 잘 설명함. 영상은 에 있음.
Rust 개발자가 !를 never 타입이라고 바로 알아볼지는 모르겠음. TypeScript에서는 never를 자주 쓰는데, Rust도 더 사람이 읽기 쉬운 긴 이름을 썼으면 학습 부담이 덜했을 듯.
예전에는 발산 함수의 반환형 외에는 안정 Rust에서 !를 쓸 일이 거의 없었음. 2012년 튜토리얼에도 있던 특수 반환형 표기를 완전한 타입으로 올리면서 그대로 재사용한 것임. Never 별칭을 두자는 의견에는 동의하고, 기존 Infallible도 그런 별칭으로 바뀌는 중임.