[Rust] 1.61.0 업데이트 발표 (번역)

https://blog.rust-lang.org/2022/05/19/Rust-1.61.0.html

우리 러스트 팀은 새 버전 [1.61.0]을 발표하게 돼서 정말 기쁩니다!

러스트는 누구든 믿음직하고 효과적인 소프트웨어를 만들 수 있게 도와주는 끝내주는 언어입니다.

만약 rustup을 통해서 Rust의 이전버전을 설치해놓은 상대라면, 업데이트는 아주 쉽습니다. 그냥 이렇게 치면 돼요.
rustup update stable

rustup을 설치한 적이 없다면, 우리 웹사이트의 설치 페이지에서 받을 수 있습니다. 그리고 깃허브에서 이번 버전에 대한 릴리즈 노트를 참조해보세요.

미래의 릴리즈를 테스트해서 러스트 팀을 돕고 싶다면, 로컬에서 베타 채널(rustup default beta) 또는 nightly 채널(rustup default nightly)로 업데이트하는 것을 고려할 수 있습니다.

버그를 발견했다면 리포트해주세요!




1.61.0엔 무엇이 있나요?


main에서의 커스텀 exit code

초기에, Rust의 main 함수는 항상 종료 상태에서 성공을 나타내는 단위 타입 ()만 반환할 수 있었고, 그렇지 않으면 process::exit(code)를 호출해야 했습니다.

Rust 1.26부터 main은 Result를 반환할 수 있게 되었습니다.
여기서 Ok는 C의 EXIT_SUCCESS로, Err은 EXIT_FAILURE로 변환되었습니다. 오류도 debug-printing을 했고요.
내부적으로 이러한 대체 리턴타입은 unstable한 Termination 트레잇으로 통합되었습니다.

이번 릴리스에서는 플랫폼별 리턴타입을 래핑하는 보다 일반적인 ExitCode 타입과 해당 Termination 트레잇이 최종적으로 안정화됩니다.

여기에는 SUCCESS와 FAILURE 상수가 있으며, 더 임의의 값을 위해 From도 구현합니다.
Termination 트레잇은 고유한 타입에 대해 구현될 수도 있으므로 ExitCode로 변환하기 전에 모든 종류의 리포팅을 커스터마이징할 수 있습니다.

예를 들어 다음은 git bisect 실행 스크립트의 exit 코드를 작성하는 타입세이프한 방법입니다.

**use std::process::{ExitCode, Termination}; **


**#[repr(u8)] **
**pub enum GitBisectResult { **
** Good = 0, **
** Bad = 1, **
** Skip = 125, **
** Abort = 255, **
**} **


**impl Termination for GitBisectResult { **
** fn report(self) -> ExitCode { **
** **** // Maybe print a message here ******
** ExitCode::from(self as u8) **
** } **
**} **


fn main() -> GitBisectResult { **
** std::panic::catch_unwind(|| { **
** todo!("test the commit") **
** })

** .unwrap_or(GitBisectResult::Abort) **
}




const fn에 대한 더 많은 기능

이번 릴리스에서는 const에서 더 많은 기능을 사용할 수 있도록 몇 가지 증분 기능이 안정화되었습니다.

**fn 포인터의 기본적인 핸들링: **
이제 const fn에서 함수 포인터를 생성, 전달, 캐스팅할 수 있습니다.
가령, 이건 인터프리터를 위한 컴파일타임 함수 테이블을 빌드하는 데 유용할 수 있습니다.
하지만 fn 포인터를 호출하는 것은 여전히 허용되지 않습니다.

**Trait bounds: **
이전에는 트레잇 바운드로 Sized만 허용되었는데, 이제는 T: Copy와 같은 것들도 const fn에 작성할 수 있습니다.

**dyn 트레잇 타입: **
마찬가지로, const fn은 이제 트레잇 객체인 dyn Trait을 처리할 수 있습니다.

**impl 트레잇 타입: **
이제 const fn의 인자 및 리턴값이 불투명한(opaque) impl Trait 타입이 될 수 있습니다.

다만, 트레잇 기능은 아직 const fn에서 트레잇들로 메서드를 호출하는 것을 지원하지는 않습니다.

const 컨텍스트의 현재 기능에 대해 자세히 알아보고 싶다면, 레퍼런스북의 Constant Evaluation 섹션을 참조하세요.
곧 생겨날 기능들은 Rust#57563에서 추적할 수 있습니다.




locked stdio에 대한 정적 핸들

3개의 표준 I/O 스트림(Stdin, Stdout, Stderr)에는 각각 lock(&self)이 있어서 읽기 및 쓰기 동기화를 더 잘 제어할 수 있습니다.
하지만 &self에서 빌려온 라이프타임으로 lock guard를 리턴했기 때문에, 원래 핸들의 범위로 제한이 됩니다.

lock이 실제로 정적 저장소에 있었기 때문에 이는 불필요한 제한으로 판단되어, 이제 guard가 핸들에서 분리된 'static 라이프타임으로 반환됩니다.

예를 들어, 일반적인 오류는 핸들을 가져와서 하나의 구문에서 lock을 걸 때 발생합니다.

**// error[E0716]: temporary value dropped while borrowed **
**let out = std::io::stdout().lock(); ******
**// ^^^^^^^^^^^^^^^^^ - temporary value is freed at the end of this statement **
**// | **
**// creates a temporary which is freed while still in use **

이제 lock guard는 'static이며, 임시로 빌려오지 않기 때문에 잘 작동합니다!




stable이 된 API들

다음의 메서드와 트레잇 구현들은 이제 stable입니다.

Pin::static_mut
Pin::static_ref
Vec::retain_mut
VecDeque::retain_mut
Write for Cursor<[u8; N]>
std::os::unix::net::SocketAddr::from_pathname
std::process::ExitCode
std::process::Termination
std:🧵:JoinHandle::is_finished

다음의 stable 함수들은 이제 const입니다!

<*const T>::offset과** <mut T>::offset*
<*const T>::wrapping_offset과** <mut T>::wrapping_offset*
<const T>::add <mut T>::add
<const T>::sub <mut T>::sub
<const T>::wrapping_add <mut T>::wrapping_add
<const T>::wrapping_sub <mut T>::wrapping_sub
<[T]>::as_mut_ptr
<[T]>::as_ptr_range
<[T]>::as_mut_ptr_range




기타 변경점

1.61 릴리즈에는 이외의 기타 변경점들도 있습니다. RustCargoClippy에서 무엇이 바뀌었는지 확인해보세요.

향후 릴리스에서는 Linux 커널에 대한 기준 요구 사항을 버전 3.2로, glibc에 대한 기준 요구 사항을 버전 2.17로 늘릴 계획입니다.
Rust#95026에 대한 피드백을 기다리겠습니다!




1.61.0의 컨트리뷰터들

1.61의 완성엔 수많은 사람들이 함께했습니다. 전부 여러분이 없었다면 불가능했을 거에요.

고마워요!​