[Rust] 1.60.0 업데이트 발표 (번역)
https://blog.rust-lang.org/2022/04/07/Rust-1.60.0.html
우리 러스트 팀은 새 버전 [1.60.0]을 발표하게 돼서 정말 기쁩니다!
러스트는 누구든 믿음직하고 효과적인 소프트웨어를 만들 수 있게 도와주는 끝내주는 언어입니다.
만약 rustup을 통해서 Rust의 이전버전을 설치해놓은 상대라면, 업데이트는 아주 쉽습니다. 그냥 이렇게 치면 돼요.
rustup update stable
rustup을 설치한 적이 없다면, 우리 웹사이트의 설치 페이지에서 받을 수 있습니다. 그리고 깃허브에서 이번 버전에 대한 릴리즈 노트를 참조해보세요.
미래의 릴리즈를 테스트해서 러스트 팀을 돕고 싶다면, 로컬에서 베타 채널(rustup default beta) 또는 nightly 채널(rustup default nightly)로 업데이트하는 것을 고려할 수 있습니다.
버그를 발견했다면 리포트해주세요!
1.60.0엔 무엇이 있나요?
소스 기반의 코드 커버리지
LLVM 기반 커버리지 계측(instrumentation)에 대한 지원이 rustc에서 안정화되었습니다.
You can try this out on your code by rebuilding your code with -Cinstrument-coverage, for example like this:
예를 들어 다음과 같이 -Cinstrument-coverage 옵션을 사용하면 코드를 재빌드해서 코드에서 이를 시도할 수 있습니다.
**RUSTFLAGS="-C instrument-coverage" cargo build **
그런 다음 결과 바이너리를 실행하면 현재 디렉터리에 default.profraw 파일이 생성됩니다.
추가로, 경로와 파일명은 환경 변수로 재정의할 수 있습니다. 자세한 내용은 문서를 참조하세요.
llvm-tools-preview 컴포넌트에는 raw 프로필 출력(커버리지 영역 실행 카운트)을 처리하고 병합하기 위한 llvm-profdata가 포함됩니다.
보고서 생성을 위한 llvm-cov도 있고요.
llvm-cov는 llvm-profdata에서 처리된 출력과 그 바이너리 자체를 결합합니다. 바이너리는 카운터에서 실제 소스코드 영역으로의 매핑을 포함하기 때문이죠.
**rustup component add llvm-tools-preview **
**$(rustc --print sysroot)/lib/rustlib/x86_64-unknown-linux-gnu/bin/llvm-profdata merge -sparse default.profraw -o default.profdata **
**$(rustc --print sysroot)/lib/rustlib/x86_64-unknown-linux-gnu/bin/llvm-cov show -Xdemangler=rustfilt target/debug/coverage-testing \ -instr-profile=default.profdata \ -show-line-counts-or-regions \ -show-instantiations **
간단한 helloworld 바이너리에 대한 위의 명령은
입력의 각 행이 포함되었음을 보여주는 주석달린 보고서를 생성합니다.
**1| 1| fn main() { **
**2| 1| println!("Hello, world!"); **
**3| 1| } **
더 자세한건 rustc book에서 해당 문서를 참고해주세요.
이 기본 기능은 안정적이며 향후 모든 Rust 릴리스에 어떤 형태로든 존재할 것입니다.
하지만 특정 출력 형식과 이걸 생성하는 LLVM 도구는 변경될 수 있습니다.
이런 이유로 llvm-tools-preview와 코드를 컴파일할때 사용되는 rustc 바이너리 모두가 동일한 버전을 사용하는지 확인하는 것이 중요합니다.
cargo --timings
Cargo는 --timings 플래그를 사용하여 빌드에 대한 정보 수집 지원을 안정화했습니다.
$ cargo build --timings Compiling hello-world v0.1.0 (hello-world) Timing report saved to target/cargo-timings/cargo-timing-20220318T174818Z.html Finished dev [unoptimized + debuginfo] target(s) in 0.98s
이 보고서는 target/cargo-timings/cargo-timing.html에도 복사됩니다.
Cargo의 릴리스 빌드에 대한 보고서는 여기에 있습니다. 이러한 보고서는 빌드 성능을 개선하는 데 유용할 수 있습니다.
timing 보고서에 대한 더 많은 정보는 문서에서 찾을 수 있습니다.
Cargo features를 위한 새 문법
이번 릴리스에는 Cargo 기능에 대한 지원과 선택적인 종속성과 상호작용하는 방식을 개선하기 위해, 네임스페이스 종속성과 약한 종속성 기능이라는 두 가지 새로운 변경사항이 도입되었습니다.
Cargo는 아래 스니펫에 설명된 것처럼 선택적 종속성과 함께 오랫동안 이런 기능을 지원했습니다.
**[dependencies] **
**jpeg-decoder = { version = "0.1.20", default-features = false, optional = true } **
**[features] **
**# jpeg-decoder의 "rayon" 기능을 활성화하여 병렬 처리 지원을 활성화합니다. ******
**parallel = ["jpeg-decoder/rayon"] **
이 예제에서 주목해야 할 두 가지 사항이 있습니다.
-
선택적 종속성 jpeg-decoder는 동일한 이름의 기능을 암시적으로 정의합니다. jpeg-decoder 기능을 사용 설정하면 jpeg-decoder 종속성이 사용 설정됩니다.
-
'jpeg-decoder/rayon' 구문은 jpeg-decoder 종속성을 활성화하고 jpeg-decoder 종속성 항목의 rayon 기능을 활성화합니다.
네임스페이스 기능은 첫 번째 문제를 해결합니다. 이제 [features] 테이블에서 dep: 접두사를 사용하여 선택적 종속성을 feature를 통해 암시적으로 노출하지 않고, 명시적으로 참조할 수 있습니다.
이렇게하면 보다 설명적인 feature 이름 뒤에 선택적 종속성을 숨기는 것을 포함해, 선택적 종속성에 해당하는 기능 정의를 더 잘 제어할 수 있습니다.
약한 종속성 기능은 '선택적 종속성/기능명' 구문이 항상 선택적 종속성을 사용하도록 설정하는 두 번째 문제를 해결합니다.
그러나 다른 기능이 선택적 종속성을 활성화한 경우에만 선택적 종속성에 대한 기능을 활성화하려는 경우가 많습니다.
그래서 1.60부터는 ?를 추가할 수 있습니다. "package-name?/feature-name"과 같이 다른 항목이 선택적 종속성을 활성화한 경우에만 지정된 기능을 활성화합니다.
예를 들어 라이브러리에 직렬화 지원을 추가했으며, 일부 선택적 종속성에서 해당 기능을 활성화해야 한다고 가정해 보겠습니다.
그럼 다음과 같이 할 수 있습니다.
**[dependencies] **
**serde = { version = "1.0.133", optional = true } **
**rgb = { version = "0.8.25", optional = true } **
**[features] **
serde = ["dep:serde", "rgb?/serde"]
이 예제에서 serde 기능을 활성화하면 serde 종속성이 활성화됩니다.
또한 rgb 종속성에 대한 serde 기능을 활성화하지만, 다른 것이 rgb 종속성을 활성화한 경우에만 가능합니다.
증분 컴파일 상태
증분 컴파일은 1.60 릴리스에서 다시 활성화됩니다.
Rust 팀은 계속해서 증분에서의 버그를 수정하는 작업을 계속하고 있지만, 현재로서는 광범위한 손상을 일으키는 문제가 알려져있지는 않으므로 증분 컴파일을 다시 활성화하기로 결정했습니다.
또한 컴파일러 팀은 이러한 종류의 미래 문제를 방지하기 위한 장기 전략을 계속 연구하고 있습니다.
이 프로세스는 초기 단계이므로 아직 공유할 내용이 없습니다.
Instant monotonicity guarantees
모든 플랫폼에서 Instant는 가능한 경우 monotonic한 동작을 보장하는 OS API를 사용하려고 시도합니다. (모든 Tier 1 플랫폼의 경우).
실제로 이러한 보장은 드문 경우지만 하드웨어, 가상화, 또는 운영체제 버그로 인해 깨집니다.
monotonic clock을 제공하지 않는 이러한 버그 및 플랫폼을 해결하기 위해 Instant::duration_since, Instant::elapsed 및 Instant::sub가 이제 0으로 포화됩니다.
이전 Rust 버전에서는 대신 패닉이 발생했습니다.
Instant::checked_duration_since를 사용하면 monotonicity 위반하거나 잘못된 순서로 인스턴트를 빼는 상황을 감지하고 처리할 수 있습니다.
이 해결 방법은 이전 인스턴스와 이후 인스턴스가 실수로 바뀌는 프로그래밍 오류를 숨깁니다.
이러한 이유로 미래의 Rust 버전은 가능하고 효율적이라면 최소한 이러한 경우에는 패닉을 다시 던질 수 있습니다.
1.60 이전에는 std의 뮤텍스나 원자성을 통해 monotonicity 보장이 제공되었으며, 이로 인해 Instant::now()에 큰 성능 오버헤드가 발생할 수 있었습니다.
또한 패닉 동작은 Rust 소프트웨어가 환경의 하위 집합에서 패닉을 일으킬 수 있음을 의미했으며, 이는 해당 소프트웨어의 작성자가 실행 중인 운영 체제, 하드웨어 또는 가상화 시스템을 수정하거나 업그레이드할 수 없기 때문에 크게 바람직하지 않습니다.
또한 이러한 환경에 예상치 못한 패닉이 발생하면 Rust 소프트웨어의 안정성과 이식성이 떨어집니다. 이는 최종 사용자에게 monotonic clock 처리에서 일반적으로 특별하지 않은 플랫폼 버그를 노출하는 것보다 더 중요한 일이죠.
Stable이 된 API들
다음 메서드와 트레잇 구현들이 stable이 되었습니다.
Arc::new_cyclic
Rc::new_cyclic
slice::EscapeAscii
<[u8]>::escape_ascii
u8::escape_ascii
Vec::spare_capacity_mut
MaybeUninit::assume_init_drop
MaybeUninit::assume_init_read
i8::abs_diff
i16::abs_diff
i32::abs_diff
i64::abs_diff
i128::abs_diff
isize::abs_diff
u8::abs_diff
u16::abs_diff
u32::abs_diff
u64::abs_diff
u128::abs_diff
usize::abs_diff
Display for io::ErrorKind
From
Not for ! (the "never" type)
_Op_Assign<$t> for Wrapping<$t>
arch::is_aarch64_feature_detected!
기타 변경점
1.60 릴리즈에는 이외의 기타 변경점들도 있습니다. Rust, Cargo, Clippy에서 무엇이 바뀌었는지 확인해보세요.
1.60.0의 컨트리뷰터들
1.60의 완성엔 수많은 사람들이 함께했습니다. 전부 여러분이 없었다면 불가능했을 거에요.