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

Rust 팀은 Rust 버전, 1.59.0 버전을 발표했습니다. Rust은 모든 사람이 신뢰할 수 있고 효율적인 소프트웨어를 구축하도록 권한을 부여하는 프로그래밍 언어입니다.

오늘은 푸틴의 군대가 우크라이나를 급습해 전 세계의 이목이 쏠린 날입니다.
새로운 Rust 릴리즈에 대한 세부 사항으로 들어가기 전에, 우리는 우크라이나 사람들과 연대하고 이 충돌의 영향을 받는 모든 사람들을 지지한다는 것을 밝히고 싶습니다.

Rustup을 통해 이전 버전의 Rust를 설치했다면 다음을 통해 1.59.0을 받을 수 있습니다.

rustup update stable

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




1.59.0 stable엔 뭐가 있나요?


인라인 어셈블리

이제 Rust 언어는 인라인 어셈블리를 지원합니다.
이를 통해 실행에 대한 매우 낮은 수준의 제어나 특수한 머신 인스트럭션이 필요한 많은 응용을 사용할 수 있어요.

예를 들어 x86-64 타겟으로 컴파일할 때 이제 다음과 같이 작성할 수 있습니다.


**use std::arch::asm; **


// shift를 사용해 x를 6으로 곱하고 더함****


**let mut x: u64 = 4; **


**unsafe { **
** asm!( **
** "mov {tmp}, {x}", **
** "shl {tmp}, 1", **
** "shl {x}, 2", **
** "add {x}, {tmp}", **
** x = inout(reg) x, **
** tmp = out(reg) _, **
** ); **
**} **
**assert_eq!(x, 4 * 6); **

asm!와 global_asm!는 레지스터의 이름을 지정할 때 Rust의 포맷 문자열을 사용합니다. 그래서 Rust 프로그래머에게 매우 친숙하게 느껴질 거에요.

인라인 어셈블리에서 사용할 수 있는 어셈블리 언어와 인스트럭션은 타겟 아키텍처에 따라 다릅니다. 오늘날 stable Rust 컴파일러는 다음 아키텍처에서 인라인 어셈블리를 지원합니다.

Rust By Example에서 인라인 어셈블리의 더 많은 예제를 볼 수 있고, 레퍼런스에서 더 자세한 문서를 찾을 수 있습니다.




구조 분해 할당

이제 튜플, 슬라이스, 구조체 패턴을 할당의 left-hand side로 사용할 수 있습니다.

**let (a, b, c, d, e); **
**(a, b) = (1, 2); **


**[c, .., d, _] = [1, 2, 3, 4, 5]; **
Struct { e, .. } = Struct { e: 5, f: 3 };


** assert_eq!([1, 2, 1, 4, 5], [a, b, c, d, e]); **

이렇게 하면 오랫동안 동일한 형태로 유지됐던 기존 let 바인딩과 비교해, 일관적인 형태가 되죠.

다만 "+="와 같은 연산자를 사용한 구조 분해 할당은 허용되지 않습니다.




Const generics 기본값과 interleaving

제네릭 타입은 이제 해당 const 제네릭에 대한 기본값을 지정할 수 있습니다.
예를 들어 이제 다음과 같이 작성할 수 있습니다.

**struct ArrayStorage<T, const N: usize = 2> { **
** arr: [T; N], **
**} **


**impl ArrayStorage { **
** fn new(a: T, b: T) -> ArrayStorage { **
** ArrayStorage { arr: [a, b], } **
** } **
**} **

그리고 이전에는 type 매개변수가 모든 const 매개변수 앞에 와야 했습니다.
해당 제한은 완화되었으며 이제 interleave할 수 있습니다.

fn cartesian_product
< T, const N: usize, U, const M: usize, V, F >
**(a: [T; N], b: [U; M], f: F) **
**-> [[V; N]; M] **
**where F: FnMut(&T, &U) -> V { **
** **** // ... ******
**} **



미래 버전의 호환성 문제 경고

때로 Rust 컴파일러의 버그로 인해 허용되어서는 안 되는 코드가 허용됩니다. safe 코드에서 허용되는 패킹된 구조체 필드의 borrow를 예로 들 수 있습니다.

이건 드물게 발생하지만, 프로젝트에서 사용하는 crate에 더 이상 허용되지 않는 코드가 있을 때 매우 끔찍한 일이 벌어질 수 있습니다.
실제로 프로젝트가 빌드를 중단할 때까지 알지 못할 수도 있어요!

Cargo는 이제 Rust의 미래 버전에서 종속성이 거부될 때 경고를 표시합니다. cargo build 또는 cargo check를 실행하면 다음과 같은 메세지를 확인할 수 있습니다.

warning: the following packages contain code that will be rejected by a future version of Rust: old_dep v0.1.0 note: to see what the problems were, use the option --future-incompat-report, or run cargo report future-incompatibilities --id 1

경고에 언급된 crate report 명령을 실행하여 거부될 코드의 전체 보고서를 볼 수 있습니다.
이렇게 하면 빌드가 중단되기 전에 종속성을 업그레이드할 시간이 생깁니다.




stripped 바이너리 생성

배포하는 바이너리에서 debuginfo와 같은 불필요한 정보를 제거하여 더 작게 만드는 것은 종종 유용한 최적화 작업입니다.

바이너리가 생성된 후 이 작업을 수행하는 것은 항상 수동으로 가능했지만, 이제 cargo와 rustc는 바이너리가 링크될 때 strip을 지원합니다.
이를 사용 설정하려면 Cargo.toml에 다음 문구를 추가하세요.

[profile.release]
strip = "debuginfo"

이러면 debuginfo가 릴리즈 바이너리에서 제거됩니다.
또한 'symbols'를 제공하거나 지원하는 경우 모든 symbol 정보를 제거하기 위해 true를 제공할 수도 있습니다.

표준 라이브러리는 일반적으로 디버그 symbol 및 라인 수준 debuginfo와 함께 제공되므로 디버그 symbol을 활성화하지 않고 빌드된 Rust 바이너리는 기본적으로 표준 라이브러리의 디버그 정보를 계속 포함합니다.
strip 옵션을 사용하면 이 추가 정보를 제거하여 더 작은 Rust 바이너리를 생성할 수 있습니다.

자세한 내용은 Cargo의 문서를 참조하세요.




증분컴파일을 기본값으로 해제

1.59.0 릴리스는 기본적으로 증분을 비활성화합니다(환경 변수: RUSTC_FORCE_INCREMENTAL=1을 통해 명시적으로 요청하면 활성화됩니다).
이렇게 하면 증분 컴파일을 켠 상태에서 컴파일하는 동안 역직렬화 오류를 일으킬 수 있는 버그 #94124의 영향이 완화됩니다.

#94124에 대한 버그 수정은 현재 1.60 베타 버전이며 6주 후에 배송될 겁니다.
우리는 현재 1.60 stable 버전에서 증분과 관련된 다른 문제를 발견하지 못했으며, 문제가 발생하지 않으면 1.60 안정 버전에서 증분 컴파일을 다시 활성화할 가능성이 높습니다.

증분 컴파일은 기본적으로 베타와 nightly 채널에서 기본적값으로 유지됩니다.

항상 그렇듯이, 우리는 사용자가 야간 및 베타 채널에서 테스트하고 발견한 문제를 보고할 것을 권장합니다.
특히 증분 버그의 경우는 손상이 있는지 여부와 영향을 받는 사용자 수를 Rust 팀이 판단할 수 있도록 하는 가장 좋은 방법입니다.




Stable이 된 API들

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

std:🧵:available_parallelism
Result::copied
Result::cloned
arch::asm!
arch::global_asm!
ops::ControlFlow::is_break
ops::ControlFlow::is_continue
TryFrom for u8
char::TryFromCharError implementing Clone, Debug, Display, PartialEq, Copy, Eq, Error
iter::zip
NonZeroU8::is_power_of_two
NonZeroU16::is_power_of_two
NonZeroU32::is_power_of_two
NonZeroU64::is_power_of_two
NonZeroU128::is_power_of_two
DoubleEndedIterator for ToLowercase
DoubleEndedIterator for ToUppercase
TryFrom<&mut [T]> for [T; N]
UnwindSafe for Once
RefUnwindSafe for Once
armv8 neon intrinsics for aarch64

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

mem::MaybeUninit::as_ptr
mem::MaybeUninit::assume_init
mem::MaybeUninit::assume_init_ref
ffi::CStr::from_bytes_with_nul_unchecked




기타 변경점

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




1.59.0의 컨트리뷰터들

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