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

https://blog.rust-lang.org/2023/11/16/Rust-1.74.0.html
러스트는 누구든 믿음직하고 효과적인 소프트웨어를 만들 수 있게 도와주는 끝내주는 언어입니다.

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

rustup update stable

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

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

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



1.74.0 stable에는 무엇이 있나요?



Cargo를 통한 린트 구성

RFC 3389에서 제안된 대로 Cargo.toml 매니페스트는 이제 컴파일러 및 기타 도구의 린트에 대한 리포팅 수준(forbid, deny, warn, allow)을 구성하기 위한 [lints] 테이블을 지원합니다.

따라서 전체 빌드에 영향을 주는 RUSTFLAGS를 -F/-D/-W/-A로 설정하거나, 아래와 같은 크레이트 레벨 attribute를 더 사용하지 않아도 되죠.

#![forbid(unsafe_code)]
#![deny(clippy::enum_glob_use)]

이제는 저런걸 쓰는 대신 Cargo의 패키지 매니페스트에 다음과 같이 작성할 수 있습니다.

[lints.rust]
unsafe_code = "forbid"


[lints.clippy]
enum_glob_use = "deny"

이는 [workspace.lints] 테이블에서 구성한 다음 다른 많은 workspace 설정과 마찬가지로 [lints] workspace = true로 상속할 수도 있습니다.

Cargo는 어떤 crate를 rebuild해야 할지 결정할 때 이러한 설정의 변경 사항도 추적합니다.

자세한 내용은 Cargo 레퍼런스 메뉴얼의 lintsworkspace.lints 섹션을 참조하세요.




Cargo Registry Authentication

이번 릴리스에는 credential providers와 authenticated private registries라는 두 가지 Cargo 관련 기능이 더 포함되어 있습니다.

Credential providers를 사용하면 Cargo가 레지스트리에 대한 credential을 얻는 방법을 구성할 수 있습니다.
Linux, macOS 및 Windows의 OS별 보안 secret 저장소를 위한 빌트인 provider가 포함되어 있습니다.

또한 토큰을 저장하거나 생성하는 임의의 방법을 지원하도록 custom provider를 작성할 수 있습니다. secure credential provider를 사용하면 레지스트리 토큰이 유출될 위험이 줄어듭니다.

이제 레지스트리는 publishing 뿐만 아니라 모든 operation에 대해 선택적으로 인증을 요구할 수 있습니다.
이를 통해 private Cargo registry는 보다 안전한 crate 호스팅을 제공할 수 있습니다.

private registry를 사용하려면 credential provider를 구성해야 합니다.

더 많은 정보를 원하신다면, Cargo docs를 참조해주세요.




opaque 리턴타입에서의 Projections

"반환타입에는 parent scope의 lifetime을 참조하는 프로젝션 또는 Self가 포함될 수 없습니다(return type cannot contain a projection or Self that references lifetimes from a parent scope)"라는 오류를 봐오셨다면, 이제는 안심하셔도 됩니다!

이제 컴파일러에서는 async fn 및 impl Trait와 같은 불투명한(opaque) 리턴타입에서 Self 및 associated types을 붙일 수 있습니다.

"projection"과 같은 전문 용어에 대해 전혀 모르더라도 괜찮습니다. 훨씬 더 예상 가능한 형태로 동작하게끔 개선될 뿐이에요.

이 기능은 그 구현이 원래 캡처된 lifetime을 제대로 처리하지 않았기 때문에 unstable한 feature gate를 가졌습니다. 그래서 일단 수정을 하긴 했지만 이게 제대로 작동하는지 확인할 시간을 가지려고 합니다.

더 많은 기술적 세부 사항은 다음 PR을 참조하세요.

이제 모두 허용되는 예제를 들어볼게요.

struct Wrapper<'a, T>(&'a T);


// Self를 언급한 불투명 리턴타입:****
impl Wrapper<'_, ()> {
** async fn async_fn() -> Self { /* ... / }*
** fn impl_trait() -> impl Iterator<Item = Self> { /* ... / }*
}


trait Trait<'a> {
** type Assoc;**
** fn new() -> Self::Assoc;**
}


impl Trait<'_> for () {
** type Assoc = ();**
** fn new() {}**
}


// associated type을 언급한 불투명 리턴타입:****
impl<'a, T: Trait<'a>> Wrapper<'a, T> {
** async fn mk_assoc() -> T::Assoc { /* ... / }*
** fn a_few_assocs() -> impl Iterator<Item = T::Assoc> { /* ... / }*
}



Stable이 된 API

core::num::Saturating
impl Fromio::Stdout for std::process::Stdio
impl Fromio::Stderr for std::process::Stdio
impl From for std::process::Child{Stdin, Stdout, Stderr}
impl From for std::process::Child{Stdin, Stdout, Stderr}
std::ffi::OsString::from_encoded_bytes_unchecked
std::ffi::OsString::into_encoded_bytes
std::ffi::OsStr::from_encoded_bytes_unchecked
std::ffi::OsStr::as_encoded_bytes
std::io::Error::other
impl TryFrom for u16
impl<T: Clone, const N: usize> From<&[T; N]> for Vec
impl<T: Clone, const N: usize> From<&mut [T; N]> for Vec
impl<T, const N: usize> From<[T; N]> for Arc<[T]>
impl<T, const N: usize> From<[T; N]> for Rc<[T]>

아래 API들은 이제 const context에서도 stable하게 사용할 수 있습니다.

core::mem::transmute_copy
str::is_ascii
[u8]::is_ascii



호환성 노트

이전에 발표한 대로 Rust 1.74는 Apple 플랫폼에 대한 요구 사항을 높였습니다.

최소 버전은 이제 이렇습니다.
macOS: 10.12 Sierra (First released 2016)
iOS: 10 (First released 2016)
tvOS: 10 (First released 2016)




기타 변경점

이외의 모든 변경사항은 각각 Rust, Cargo, Clippy에서 확인하세요.




1.74.0의 컨트리뷰터들에게

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

고마워요!