• 2311rust,到74版本更新


    1.66.0稳定版

    显式判定有字段的枚举

    即使有字段,带整数表示的枚举现在也可用显式判定器.

    #[repr(u8)]
    enum Foo {
        A(u8),
        B(i8),
        C(bool) = 42,
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    跨语言边界传递值时,在两个语言中匹配枚举表示时,显式判定器非常有用.如

    #[repr(u8)]
    enum Bar {
        A,
        B,
        C = 42,
        D,
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    这里保证Bar枚举有与u8相同的布局.此外,Bar::C变体保证为42.
    同时,如果只需要不透明的判定句柄,见std::mem::discriminant函数.

    core::hint::black_box

    基准测试或检查编译器生成的机器代码时,有时避免优化很有用.以下示例中,push_cap函数,在循环中执行了4Vec::push:

    fn push_cap(v: &mut Vec<i32>) {
        for i in 0..4 {
            v.push(i);
        }
    }
    pub fn bench_push() -> Duration { 
        let mut v = Vec::with_capacity(4);
        let now = Instant::now();
        push_cap(&mut v);
        now.elapsed()
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    如果在x86_64上检查编译器的优化输出,会注意到它很短:

    example::bench_push:
      sub rsp, 24
      call qword ptr [rip + std::time::Instant::now@GOTPCREL]
      lea rdi, [rsp + 8]
      mov qword ptr [rsp + 8], rax
      mov dword ptr [rsp + 16], edx
      call qword ptr [rip + std::time::Instant::elapsed@GOTPCREL]
      add rsp, 24
      ret
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    事实上,整个push_cap函数,都已优化掉了!

    可用新稳定的black_box函数来解决它.从功能上讲,black_box不是很有趣:它接受传递它的值,然后把返回它.

    然而,在内部,编译器将black_box视为,可任意处理输入返回值(即名字)的一个函数.
    它对禁止优化很有用.如,可向编译器暗示,在每次for循环迭代后,如何用向量.

    use std::hint::black_box;
    fn push_cap(v: &mut Vec<i32>) {
        for i in 0..4 {
            v.push(i);
            black_box(v.as_ptr());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    现在,可在优化汇编输出中找到展开for循环:

      mov dword ptr [rbx], 0
      mov qword ptr [rsp + 8], rbx
      mov dword ptr [rbx + 4], 1
      mov qword ptr [rsp + 8], rbx
      mov dword ptr [rbx + 8], 2
      mov qword ptr [rsp + 8], rbx
      mov dword ptr [rbx + 12], 3
      mov qword ptr [rsp + 8], rbx
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    还可在此汇编输出中看到调用black_box的副作用.在每次迭代后都会无用地重复mov qword ptr[rsp+8],rbx指令.

    它把v.as_ptr()地址写入函数的从未实际调用第一个参数.

    注意,生成代码不关心推(push)调用引入的分配.这是因为在bench_push函数中调用Vec::with_capacity(4).

    可到处试放置black_box,或在多个位置试使用它,以查看它对编译器优化的影响.

    cargo remove

    Rust1.62.0中,引入了命令行项目添加依赖项cargo add工具.现在,可用cargo remove来删除依赖项.

    稳定的API

    proc_macro::Span::source_text
    u*::{checked_add_signed, overflowing_add_signed, saturating_add_signed, wrapping_add_signed}
    i*::{checked_add_unsigned, overflowing_add_unsigned, saturating_add_unsigned, wrapping_add_unsigned}
    i*::{checked_sub_unsigned, overflowing_sub_unsigned, saturating_sub_unsigned, wrapping_sub_unsigned}
    BTreeSet::{first, last, pop_first, pop_last}
    BTreeMap::{first_key_value, last_key_value, first_entry, last_entry, pop_first, pop_last}
    在`WASI`上为`stdio`锁类型,添加`AsFd`实现.
    impl TryFrom<Vec<T>> for Box<[T; N]>
    core::hint::black_box
    Duration::try_from_secs_{f32,f64}
    Option::unzip
    std::os::fd
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    其他更改

    1,现在可在模式中用..=X区间.
    2,Linux版本现在分别使用LTOBolt优化了rustc前端和LLVM后端,从而提高了运行时性能和内存使用率.

    1.67.0稳定版

    #[must_use]在异步函数上有效

    现在,带#[must_use]注解的异步函数,应用该属性impl Future返回的输出.Future特征自身已用#[must_use]注解,因此所有实现Future的类型都自动为#[must_use].

    1.67中,编译器现在会在未使用输出时发出警告.

    #[must_use]
    async fn bar() -> u32 { 0 }
    async fn caller() {
        bar().await;
    }
    warning: unused output of future returned by `bar` that must be used
     --> src/lib.rs:5:5
      |
    5 |     bar().await;
      |     ^^^^^^^^^^^
      |
      = note: `#[warn(unused_must_use)]` on by default
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    已更新std::sync::mpsc实现

    标准库已有个多生产者,单消费者通道,但在该版本中,已把实现切换为基于crossbeam-channel.
    稳定的API

    {integer}::checked_ilog
    {integer}::checked_ilog2
    {integer}::checked_ilog10
    {integer}::ilog
    {integer}::ilog2
    {integer}::ilog10
    NonZeroU*::ilog2
    NonZeroU*::ilog10
    NonZero*::BITS
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    这些API现在在环境中是稳定的:

    char::from_u32
    char::from_digit
    char::to_digit
    core::char::from_u32
    core::char::from_digit
    
    • 1
    • 2
    • 3
    • 4
    • 5

    1.68.0稳定版

    Cargo的稀疏协议

    稳定了Cargo的"稀疏"注册表协议.
    访问crates.io时,新协议会显著改进性能,因为它只下载你实际使用的仓库子集的信息.
    要将稀疏协议crates.io一起使用,请设置环境变量CARGO_REGISTRIES_CRATES_IO_PROTOCOL=sparse,或编辑.cargo/config.toml文件以添加:

    [registries.crates-io]
    protocol = "sparse"
    
    • 1
    • 2

    本地固定结构

    pin!宏从T式以本地状态匿名抓来构造Pin<&mut T>.一般叫固定栈,但该"栈"也可是异步函数抓状态.此宏类似如tokio::pin!这些仓库,但标准库可利用Pin内部结构和临时生命期扩展来得到更像表达式的宏.

    ///完成运行未来.
    fn block_on<F: Future>(future: F) -> F::Output {
        let waker_that_unparks_thread = todo!();
        let mut cx = Context::from_waker(&waker_that_unparks_thread);
        //固定未来,以便可轮询它.
        let mut pinned_future = pin!(future);
        loop {
            match pinned_future.as_mut().poll(&mut cx) {
                Poll::Pending => thread::park(),
                Poll::Ready(result) => return result,
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    此例中,把原始future移动到一个临时的局部,由Pin<&mut F>类型的新pinned_future引用它,且该pin受普通借用检查器的约束,以确保不会出域.

    默认alloc错误处理器

    Rust中的分配失败时,像Box::newVec::pushAPI无法指示失败,因此需要一些不同执行路径.
    使用std仓库时,程序打印到stderr并中止.从Rust1.68.0开始,包含std二进制文件继续这样.但在分配失败时,不包括std,而只包括alloc二进制文件,现在会恐慌!
    如果需要,可通过#[panic_handler]进一步调整.
    将来,也可能会更改std的行为,以匹配仅分配的二进制文件的行为.

    稳定的API

    {core,std}::pin::pin!
    impl From<bool> for {f32,f64}
    std::path::MAIN_SEPARATOR_STR
    impl DerefMut for PathBuf
    
    • 1
    • 2
    • 3
    • 4

    这些API现在在环境中是稳定的:

    VecDeque::new
    
    • 1

    其他更改

    如前,Rust中的安卓平台支持现在以NDKr25为目标,这对应于支持的最低API级别19(KitKat).

    1.69.0稳定版

    Rust1.69.0未引入重大的新功能.但是,它包含许多小的改进.
    Cargo现在建议自动修复一些警告
    Rust1.29.0添加了cargo fix子命令,可自动修复一些简单的编译器警告.
    此外,还可自动修复一些简单Clippy警告.

    Cargo建议,检测到可自动修复警告时运行cargo fixcargo clippy --fix:

    warning: unused import: `std::hash::Hash`
     --> src/main.rs:1:5
      |
    1 | use std::hash::Hash;
      |     ^^^^^^^^^^^^^^^
      |
      = note: `#[warn(unused_imports)]` on by default
     警告:`'foo'(bin"foo")`生成了1个警告(运行`'cargo fix--bin"foo"'`以应用1个建议)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    注意,仅当想精确修复时,才需要上面显示的完整Cargo调用.如果要修复所有,则简单的cargo fix(无其他参数)就足够了.

    默认,构建脚本中不再包含调试信息

    为了提高编译速度,Cargo现在默认在构建脚本中避免发出调试信息.只是生成脚本中的回溯包含较少的信息.
    如果要调试构建脚本,可添加以下代码片到Cargo.toml中,以再次发出调试信息:

    [profile.dev.build-override]
    debug = true
    [profile.release.build-override]
    debug = true
    
    • 1
    • 2
    • 3
    • 4

    稳定的API

    CStr::from_bytes_until_nul
    core::ffi::FromBytesUntilNulError
    
    • 1
    • 2

    可常:

    SocketAddr::new
    SocketAddr::ip
    SocketAddr::port
    SocketAddr::is_ipv4
    SocketAddr::is_ipv6
    SocketAddrV4::new
    SocketAddrV4::ip
    SocketAddrV4::port
    SocketAddrV6::new
    SocketAddrV6::ip
    SocketAddrV6::port
    SocketAddrV6::flowinfo
    SocketAddrV6::scope_id
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    1.70.0稳定版

    默认,crates.io为稀疏

    如果,要保留使用由GitHub管理的git索引的先前默认值,则可用registries.crates-io.protocol配置设置来更改默认值.

    OnceCellOnceLock

    一次初化共享数据,已稳定了两个新类型,即OnceCell及线安版的OnceLock.可在不需要立即构造要求全局常数时用它.

    use std::sync::OnceLock;
    static WINNER: OnceLock<&str> = OnceLock::new();
    fn main() {
        let winner = std::thread::scope(|s| {
            s.spawn(|| WINNER.set("thread"));
            std::thread::yield_now(); //给他们一个机会......
            WINNER.get_or_init(|| "main")
        });
        println!("{winner} wins!");
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    过去,像lazy_staticonce_cell仓库已满足了该需求,但现在它们是从once_cellunsyncsync模块移植而来的标准库的一部分.

    未来要稳定更多,如存储其初化函数的配套LazyCellLazyLock类型,但当前应已涵盖了许多用例.

    IsTerminal

    is_terminal,确定给定的文件描述符或句柄是否表示终端或TTY.这是另一个(如attyis-terminal的)标准化外部仓库中存在的功能,在Unix目标上使用C库的isatty函数和其他地方的类似函数.

    常见的用例是,让程序区分在脚本或交互模式下运行,如交互渲染颜色甚至完整的TUI.

    use std::io::{stdout, IsTerminal};
    fn main() {
        let use_color = stdout().is_terminal();
        //请给`程序输出`添加颜色代码...
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    调试信息的名字级别

    在测试CLI中强制稳定性

    稳定的API

    NonZero*::MIN/MAX
    BinaryHeap::retain
    Default for std::collections::binary_heap::IntoIter
    Default for std::collections::btree_map::{IntoIter, Iter, IterMut}
    Default for std::collections::btree_map::{IntoKeys, Keys}
    Default for std::collections::btree_map::{IntoValues, Values}
    Default for std::collections::btree_map::Range
    Default for std::collections::btree_set::{IntoIter, Iter}
    Default for std::collections::btree_set::Range
    Default for std::collections::linked_list::{IntoIter, Iter, IterMut}
    Default for std::vec::IntoIter
    Default for std::iter::Chain
    Default for std::iter::Cloned
    Default for std::iter::Copied
    Default for std::iter::Enumerate
    Default for std::iter::Flatten
    Default for std::iter::Fuse
    Default for std::iter::Rev
    Default for std::slice::Iter
    Default for std::slice::IterMut
    Rc::into_inner
    Arc::into_inner
    std::cell::OnceCell
    Option::is_some_and
    NonNull::slice_from_raw_parts
    Result::is_ok_and
    Result::is_err_and
    std::sync::atomic::Atomic*::as_ptr
    std::io::IsTerminal
    std::os::linux::net::SocketAddrExt
    std::os::unix::net::UnixDatagram::bind_addr
    std::os::unix::net::UnixDatagram::connect_addr
    std::os::unix::net::UnixDatagram::send_to_addr
    std::os::unix::net::UnixListener::bind_addr
    std::path::Path::as_mut_os_str
    std::sync::OnceLock
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    1.71.0稳定版

    C展开ABI

    1.71.0稳定了C-unwind(及其他-unwind后缀的ABI变体).

    1,除了使用-unwind时,每个ABI基本上等同于没有-unwind的相同ABI,当展开操作(panicC++风格异常)跨越ABI边界时,则行为是安全的.

    2,对panic=unwind,这是个有效方法,可无需终止进程(只要异常是用相同语言抓的),让A语言的异常按B语言展开栈;
    3,对panic=abort,这一般会立即中止进程.

    调试器可视化属性

    1.71.0稳定了对新属性的支持,#[debug_visualizer(natvis_file="...")]#[debug_visualizer(gdb_script_file="...")],
    来允许把描述NatvisGDB脚本嵌入到Rust库中,以在检查这些库创建的数据结构时,改进调试器输出.
    Rust自身已为标准库打包了一段时间的类似脚本,但此功能让库作者享受类似体验.

    细节

    raw-dylib链接

    窗口平台上,Rust现在无需构建时使用这些库,用#[link]的新kind="raw-dylib"选项,就支持使用动态库中的函数.

    简化了为窗口库提供绑定仓库.

    Rust还支持使用新的#[link_ordinal]属性,通过序号而不是命名符号来绑定到DLL提供的符号.

    升级到musl1.2

    如前,Rust1.71更新musl版本到1.2.3.大多数用户不应受到此更改的影响.

    常量初化的线本变量

    Rust1.59.0在标准库中稳定了初化线本支持,来允许更优化的生成代码.
    注意,在其他环境中,该稳定性不会使const{...}成为有效的表达式或语法;这是个单独的且当前不稳定的功能.

    use std::cell::Cell;
    thread_local! {
        pub static FOO: Cell<u32> = const { Cell::new(1) };
    }
    
    • 1
    • 2
    • 3
    • 4

    稳定的API

    CStr::is_empty
    BuildHasher::hash_one
    NonZeroI*::is_positive
    NonZeroI*::is_negative
    NonZeroI*::checked_neg
    NonZeroI*::overflowing_neg
    NonZeroI*::saturating_neg
    NonZeroI*::wrapping_neg
    Neg for NonZeroI*
    Neg for &NonZeroI*
    From<[T; N]> for (T...) (对N in 1..=12,array to N-tuple )
    From<(T...)> for [T; N] (对N in 1..=12,N-tuple to array )
    windows::io::AsHandle for Box<T>
    windows::io::AsHandle for Rc<T>
    windows::io::AsHandle for Arc<T>
    windows::io::AsSocket for Box<T>
    windows::io::AsSocket for Rc<T>
    windows::io::AsSocket for Arc<T>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    这些API现在在环境中是稳定的:

    <*const T>::read
    <*const T>::read_unaligned
    <*mut T>::read
    <*mut T>::read_unaligned
    ptr::read
    ptr::read_unaligned
    <[T]>::split_at
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    1.72.0稳定版

    Rust在错误中报告可能有用的cfg禁止项

    可用cfg有条件地启用Rust代码,如仅使用某些仓库功能提供的某些功能,或仅在指定平台上提供的某些功能.

    以前,这样禁止的项目,编译器不可见.不过,现在编译器会记住这些项名cfg条件,因为要启用仓库功能,可报告(如)你试调用的函数是否可用.

       Compiling my-project v0.1.0 (/tmp/my-project)
    error[E0432]: unresolved import `rustix::io_uring`
       --> src/main.rs:1:5
        |
    1   | use rustix::io_uring;
        |     ^^^^^^^^^^^^^^^^ no `io_uring` in the root
        |
    note: found an item that was configured out
       --> /home/username/.cargo/registry/src/index.crates.io-6f17d22bba15001f/rustix-0.38.8/src/lib.rs:213:9
        |
    213 | pub mod io_uring;
        |         ^^^^^^^^
        = note: the item is gated behind the `io_uring` feature
     有关此错误的细节,请试`"rustc--explainE0432".`
     错误:因为之前的错误,无法编译`"my-project"(bin"my-project")`
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    求值时间现在是无限的

    为了避免用户提供的计算进入编译时无限循环,或在编译时占用无限时间,Rust之前限制了作为给定常量计算的一部分运行的最大语句数.

    现在,你可在编译时无穷常量计算.为了长时间无反馈的编译,会定时报告消息.

    默认,编译器还会在执行大量步骤后发出默认拒绝的lint(const_eval_long_running)以抓无限循环,但你可允许(const_eval_long_running)允许特别长的常量计算.

    Clippy提升的检查

    rustc中,已拉入Clippy中的几个lint:
    1,clippy::undropped_manually_dropsundropped_manually_drops(拒绝)
    ManuallyDrop不会删除其内部值,因此调用std::mem::drop会闲着.相反,检查会先建议ManuallyDrop::into_inner,或可用不安全的ManuallyDrop::drop原位运行析构器.
    默认,拒绝此lint.

    2,clippy::invalid_utf8_in_uncheckedinvalid_from_utf8_unchecked(拒绝)和invalid_from_utf8(警告)
    第一个用无效的UTF-8文本,检查std::str::from_utf8_uncheckedstd::str::from_utf8_unchecked_mut调用,是否违反了安全前提,从而导致未定义行为.
    默认,拒绝此lint.
    第二个用无效的UTF-8文本,调用std::str::from_utf8std::str::from_utf8_mut,检查是否总是返回错误.默认,此lint是警告.

    3,clippy::cmp_naninvalid_nan_comparisons(警告)
    检查f32::NANf64::NAN的比较.NaN的这些比较总是错误的.
    默认,此lint是个警告,并建议改为调用is_nan()方法.
    4,clippy::cast_ref_to_mutinvalid_reference_casting(允许)
    不用内部可变性,检查&T&mutT的转换,即使未使用引用,这也是即时未定义行为.

    稳定的API

    impl<T: Send> Sync for mpsc::Sender<T>
    impl TryFrom<&OsStr> for &str
    String::leak
    
    • 1
    • 2
    • 3

    这些API现在在环境中是稳定的:

    CStr::from_bytes_with_nul
    CStr::to_bytes
    CStr::to_bytes_with_nul
    CStr::to_str
    
    • 1
    • 2
    • 3
    • 4

    1.73.0稳定版Cleaner恐慌消息中

    已更改默认panic处理器生成的输出为在其自己的行上放置panic消息,而不是用引号括起来.这样更易阅读紧急消息,如下例所示:

    fn main() {
        let file = "ferris.txt";
        panic!("oh no! {file: } not found!");
    }
    
    • 1
    • 2
    • 3
    • 4

    Rust1.73之前的输出:

    thread 'main' panicked at 'oh no! "ferris.txt" not found!', src/main.rs:3:5
    
    • 1

    Rust1.73开始的输出:

    thread 'main' panicked at src/main.rs:3:5:
    oh no! "ferris.txt" not found!
    
    • 1
    • 2

    消息很长,包含嵌套引号或跨越多行时,特别有用.
    此外,已修改assert_eqassert_ne生成的紧急消息,移动了自定义消息(第三个参数),并删除了一些不必要的标点符号,如下:

    fn main() {
        assert_eq!("  ", "  ", "ferris is not a fish");
    }
    
    • 1
    • 2
    • 3

    Rust1.73之前的输出:

    thread 'main' panicked at 'assertion failed: `(left == right)`
     left: `"  "`,
    right: `"  "`: ferris is not a fish', src/main.rs:2:5
    
    • 1
    • 2
    • 3

    Rust1.73开始的输出:

    thread 'main' panicked at src/main.rs:2:5:
    assertion `left == right` failed: ferris is not a fish
     left: "  "
    right: "  "
    
    • 1
    • 2
    • 3
    • 4

    初化线本

    正如RFC3184中所提议的,现在可直接使用get(),set(),take()replace()方法,而不是像对泛型LocalKey那样通过with(|inner|...)闭包跳转,来操作LocalKey>LocalKey>.LocalKey是静态thread_local!.

    新方法使通用代码更加简洁,并避免对新线程,为在thread_local!中指定的默认值运行额外初化代码.

    thread_local! {
        static THINGS: Cell<Vec<i32>> = Cell::new(Vec::new());
    }
    fn f() {
        //以前:
        THINGS.with(|i| i.set(vec![1, 2, 3]));
        //现在:
        THINGS.set(vec![1, 2, 3]);
        //...
        //以前:
        let v = THINGS.with(|i| i.take());
        //现在:
        let v: Vec<i32> = THINGS.take();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    稳定的API

    Unsigned {integer}::div_ceil
    Unsigned {integer}::next_multiple_of
    Unsigned {integer}::checked_next_multiple_of
    std::ffi::FromBytesUntilNulError
    std::os::unix::fs::chown
    std::os::unix::fs::fchown
    std::os::unix::fs::lchown
    LocalKey::<Cell<T>>::get
    LocalKey::<Cell<T>>::set
    LocalKey::<Cell<T>>::take
    LocalKey::<Cell<T>>::replace
    LocalKey::<RefCell<T>>::with_borrow
    LocalKey::<RefCell<T>>::with_borrow_mut
    LocalKey::<RefCell<T>>::set
    LocalKey::<RefCell<T>>::take
    LocalKey::<RefCell<T>>::replace
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    这些API现在在环境中是稳定的:

    rc::Weak::new
    sync::Weak::new
    NonNull::as_ref
    
    • 1
    • 2
    • 3

    1.74.0稳定版

    通过Cargo配置检查器

    正如RFC3389中所建议的,Cargo.toml清单现在支持[lints]表,来配置编译器和其他工具的检查器的(禁止,拒绝,警告,允许)报告级别.
    因此,与其使用会影响整个构建-F/-D/-W/-A设置RUSTFLAGS,你可用仓库级别的属性,如:

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

    现在可在包清单中编写这些内容,以便Cargo处理:

    [lints.rust]
    unsafe_code = "forbid"
    
    [lints.clippy]
    enum_glob_use = "deny"
    
    • 1
    • 2
    • 3
    • 4
    • 5

    也可在[workspace.lints]表中配置它,然后像许多其他工作区设置一样由[lints]workspace=true继承.在要决定重建哪些仓库时,Cargo还可跟踪这些设置的更改.

    更多信息,见Cargo参考手册的lintsworkspace.lints节.

    不透明返回类型中的投影

    如果曾经收到过错误"返回类型不能包含引用父域生命期的投影Self",现在可高枕无忧了!现在在不透明返回类型中,编译器允许提及Self关联类型,如async fn->impl Trait.

    示例:

    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() {}
    }
    //提及关联类型的不透明返回类型:
    impl<'a, T: Trait<'a>> Wrapper<'a, T> {
        async fn mk_assoc() -> T::Assoc { /*...*/ }
        fn a_few_assocs() -> impl Iterator<Item = T::Assoc> { /*...*/ }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    稳定的API

    core::num::Saturating
    impl From<io::Stdout> for std::process::Stdio
    impl From<io::Stderr> for std::process::Stdio
    impl From<OwnedHandle> for std::process::Child{Stdin, Stdout, Stderr}
    impl From<OwnedFd> 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<char> for u16
    impl<T: Clone, const N: usize> From<&[T; N]> for Vec<T>
    impl<T: Clone, const N: usize> From<&mut [T; N]> for Vec<T>
    impl<T, const N: usize> From<[T; N]> for Arc<[T]>
    impl<T, const N: usize> From<[T; N]> for Rc<[T]>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    这些API现在在环境中是稳定的:

    core::mem::transmute_copy
    str::is_ascii
    [u8]::is_ascii
    
    • 1
    • 2
    • 3
  • 相关阅读:
    Spring高手之路5,Dubbo服务注册与发现(文末送书)
    Java——HttpClient爬取网页,jsoup解析网页
    如何使用drawio画流程图以及导入导出
    LeetCode //C - 190. Reverse Bits
    Linux下安装mysql的几种方式
    《论文阅读》LORA:大型语言模型的低秩自适应 2021
    C++ Windows Socket 简单示例
    ubuntu1804发布kitti数据集的gps资料,imu资料(包含发布图片,点云过程)
    如何通俗理解逻辑回归(Logistic Regression)
    java复习回顾
  • 原文地址:https://blog.csdn.net/fqbqrr/article/details/134511770