小编Luk*_*odt的帖子

当enum变量已知时展开内部类型

我有这个枚举类型:

enum Animal {
    Dog(i32),
    Cat(u8),
}
Run Code Online (Sandbox Code Playgroud)

现在我有一个将此类型作为参数的函数.我知道(出于某种原因)输入总是一个Cat.我想实现这个目标:

fn count_legs_of_cat(animal: Animal) -> u8 {
    if let Animal::Cat(c) = animal { c } else { unreachable!() }
}
Run Code Online (Sandbox Code Playgroud)

我可以写这个更短和/或更惯用的吗?

enums rust

12
推荐指数
3
解决办法
4396
查看次数

我该如何调试宏?

所以我有以下宏代码我正在尝试调试.我是从Rust Book的"The Deep end"一节中读到的.我重命名宏中的变量,以更密切地关注这篇文章.

我的目标是让程序打印出BCT程序的每一行.我很清楚这是编译器很重.

rustc给我的唯一错误是:

user@debian:~/rust/macros$ rustc --pretty expanded src/main.rs -Z unstable-options > src/main.precomp.rs
src/main.rs:151:34: 151:35 error: no rules expected the token `0`
src/main.rs:151     bct!(0, 1, 1, 1, 0, 0, 0; 1, 0);
Run Code Online (Sandbox Code Playgroud)

我可以采取什么步骤,以找出其中的宏观问题是从哪里来的?

这是我的代码:

fn main() {
{
    // "Bitwise Cyclic Tag" automation through macros
    macro_rules! bct {
        // cmd 0:  0 ... => ...
        (0, $($program:tt),* ; $_head:tt)
            => (bct_p!($($program),*, 0 ; ));
        (0, $($program:tt),* ; $_head:tt, $($tail:tt),*)
            => …
Run Code Online (Sandbox Code Playgroud)

rust rust-macros

11
推荐指数
2
解决办法
6494
查看次数

如何告诉Cargo使用git存储库作为间接依赖的源而不是crates.io?

几天前,通过Emscripten对JavaScript进行交叉编译终于在夜间播出.我想以glium这种方式编译项目.但是,许多板条箱中仍然存在许多与Emscripten相关的错误.虽然维护人员通常会快速修复这些错误,但他们并不一定立即将这些错误修复程序发布到crates.io.

在我的情况下,glium取决于glutin.glutin有一个现在修复的错误,但只在git存储库中,而不是在crates.io. 注意:glutin不是我项目的直接依赖; 只是一个间接的通过glium!

我怎么知道货物使用glutin存储库作为来源glutin,而不是crates.io

rust rust-cargo

11
推荐指数
1
解决办法
1763
查看次数

在发布模式下编译时,为什么Godbolt编译器浏览器不显示我的函数的任何输出?

我想使用https://rust.godbolt.org查看此函数的程序集输出:

fn add(a: u8, b: u8) -> u8 {
    a + b
}
Run Code Online (Sandbox Code Playgroud)

在网站上粘贴这个工作正常,但显示了很多组装.鉴于rustc默认情况下在调试模式下编译我的代码,这并不奇怪.当我通过传递-O给编译器在发布模式下编译时,根本没有输出!

我究竟做错了什么?为什么Rust编译器会在发布模式下删除所有内容?

rust

11
推荐指数
1
解决办法
2010
查看次数

为什么Rust优化器不会删除那些无用的指令(在Godbolt Compiler Explorer上测试)?

我想看看一个小的Rust函数的程序集输出:

pub fn double(n: u8) -> u8 {
    n + n
}
Run Code Online (Sandbox Code Playgroud)

我使用Godbolt Compiler Explorer来生成和查看程序集(-O当然还有标志).它显示了这个输出:

example::double:
    push    rbp
    mov     rbp, rsp
    add     dil, dil
    mov     eax, edi
    pop     rbp
    ret
Run Code Online (Sandbox Code Playgroud)

现在我有点困惑,因为有这似乎并没有做任何有用的几个指令:push rbp,mov rbp, rsppop rbp.根据我的理解,我认为单独执行这三个指令没有任何副作用.那么为什么Rust优化器不会删除那些无用的指令呢?


为了比较,我还测试了一个C++版本:

unsigned char doubleN(unsigned char n) {
    return n + n;
}
Run Code Online (Sandbox Code Playgroud)

程序集输出(带-O标志):

doubleN(unsigned char): # @doubleN(unsigned char)
    add dil, dil
    mov eax, edi
    ret
Run Code Online (Sandbox Code Playgroud)

事实上,这里缺少上面那些"无用的"指令,正如我对优化输出所期望的那样.

assembly x86-64 rust llvm-codegen

11
推荐指数
1
解决办法
518
查看次数

在Rust中实现类似于C++的`std :: remove_reference`的东西?

如果类型是引用,我想有一个工具从类型中删除引用.像这样的东西(伪代码):

remove_ref(i32)      == i32
remove_ref(&i32)     == i32
remove_ref(&&i32)    == i32
remove_ref(&mut i32) == i32
Run Code Online (Sandbox Code Playgroud)

C++ std::remove_reference在标准库中有完全符合我的要求.我尝试在Rust中实现相同的功能,但我无法使其正常工作.现在,在Rust中"输出"类型的唯一方法是关于特征的关联类型(我认为).我试过这样的事情(游乐场):

#![feature(specialization)]

trait RemoveRef {
    type WithoutRef;
}

default impl<T> RemoveRef for T {
    type WithoutRef = T;
}

impl<'a, T: RemoveRef> RemoveRef for &'a T {
    type WithoutRef = T::WithoutRef;
}
Run Code Online (Sandbox Code Playgroud)

事实上,这编译.有希望!(是的,这还没有考虑到可变引用).但是,当我尝试使用它时,一切都会爆炸:

let _: <i32 as RemoveRef>::WithoutRef = 3;
let _: <&i32 as RemoveRef>::WithoutRef = 3;
let _: <&&i32 as RemoveRef>::WithoutRef = 3;
Run Code Online (Sandbox Code Playgroud)

第一行导致"溢出评估要求i32: RemoveRef".另外两行产生错误"特征限制&i32: RemoveRef不满足".我不确定我是否只是不理解这一点,或者是否打破了专业化.(相关:我在这里 …

rust

11
推荐指数
1
解决办法
361
查看次数

为什么对于许多基本类型都存在一种“原子*”类型,而不是通用的“原子&lt;T&gt;”类型?

综观std::sync::atomic模块,可以看到很多不同的Atomic*类型,如AtomicU32AtomicI16和更多。这是为什么?

锈病泛型和-在我看来-这将是可能增加一个通用的Atomic<T>,其中T由模块中定义的一些特质界(在Java中上下的命名:Atomicable)。该特征将通过可以以原子方式处理的类型来实现,并且用户可以使用Atomic<u32>而不是AtomicU32

为什么没有通用名称Atomic<T>?为什么会有许多不同的类型呢?

atomic rust

11
推荐指数
1
解决办法
199
查看次数

有哪些类型的宏/语法扩展/编译器插件?

我很困惑Rust生态系统中用于几个宏观事物的许多术语.有人可以澄清一下哪些宏/语法扩展/编译器插件以及解释这些术语之间的关系?

macros rust

10
推荐指数
1
解决办法
480
查看次数

这个错误是由于编译器对RefCell的特殊了解吗?

fn works<'a>(foo: &Option<&'a mut String>, s: &'a mut String) {}
fn error<'a>(foo: &RefCell<Option<&'a mut String>>, s: &'a mut String) {}

let mut s = "hi".to_string();

let foo = None;
works(&foo, &mut s);

// with this, it errors
// let bar = RefCell::new(None);
// error(&bar, &mut s);

s.len();
Run Code Online (Sandbox Code Playgroud)

如果我在注释中添加两行,则会发生以下错误:

error[E0502]: cannot borrow `s` as immutable because it is also borrowed as mutable
  --> <anon>:16:5
   |
14 |     error(&bar, &mut s);
   |                      - mutable borrow occurs here
15 |     
16 |     s.len(); …
Run Code Online (Sandbox Code Playgroud)

rust borrow-checker

10
推荐指数
1
解决办法
140
查看次数

编译器(特别是rustc)是否可以真正简化三角形求和以避免循环?怎么样?

在Blandy和Orendorff 的《Programming Rust》的第322页上是这样的说法:

...铁锈...认识到,有一种简单的方法可以将数字从1 n求和:总和始终等于n * (n+1) / 2

这当然是相当众所周知的等效项,但是编译器如何识别它?我猜这是在LLVM优化过程中进行的,但是LLVM是否以某种方式从第一原理中推导了等效性,或者它只是具有一些可以简化为算术运算的“公共循环计算”?

compiler-construction compiler-optimization rust llvm-codegen

10
推荐指数
1
解决办法
136
查看次数