type Arg = Vec<u8>;
#[unsafe(no_mangle)]
fn test(this: &mut Option<Arg>, arg: Arg) {
*this = Some(arg);
let Some(arg) = this else {
unreachable!()
};
black_box(arg);
}
With rust v1.98.0, its assembly:
test:
pushq %r14
pushq %rbx
pushq %rax
movq %rsi, %r14
movq %rdi, %rbx
movq (%rdi), %rsi
testq %rsi, %rsi
jle .LBB5_2
movq 8(%rbx), %rdi
movl $1, %edx
callq *__rustc::__rust_dealloc@GOTPCREL(%rip)
.LBB5_2:
movups (%r14), %xmm0
movups %xmm0, (%rbx)
movq 16(%r14), %rax
movq %rax, 16(%rbx)
cmpq $-1, (%rbx)
je .LBB5_4
movq %rbx, (%rsp)
movq %rsp, %rax
#APP
#NO_APP
addq $8, %rsp
popq %rbx
popq %r14
retq
.LBB5_4:
leaq .Lanon.6f8eaf9bed218e625010b376854c49ff.1(%rip), %rdi
leaq .Lanon.6f8eaf9bed218e625010b376854c49ff.3(%rip), %rdx
movl $40, %esi
callq *core::panicking::panic@GOTPCREL(%rip)
.Lanon.6f8eaf9bed218e625010b376854c49ff.1:
.ascii "internal error: entered unreachable code"
.Lanon.6f8eaf9bed218e625010b376854c49ff.2:
.asciz "src/main.rs"
.Lanon.6f8eaf9bed218e625010b376854c49ff.3:
.quad .Lanon.6f8eaf9bed218e625010b376854c49ff.2
.asciz "\013\000\000\000\000\000\000\000\b\000\000\000\b\000\000"
But when I change Arg to Box<[u8]>, the unreachable!() can be optimized away:
type Arg = Box<[u8]>;
#[unsafe(no_mangle)]
fn test(this: &mut Option<Arg>, arg: Arg) {
*this = Some(arg);
let Some(arg) = this else {
unreachable!()
};
black_box(arg);
}
test:
pushq %r15
pushq %r14
pushq %rbx
subq $16, %rsp
movq %rdx, %rbx
movq %rsi, %r15
movq %rdi, %r14
movq (%rdi), %rdi
testq %rdi, %rdi
je .LBB5_3
movq 8(%r14), %rsi
testq %rsi, %rsi
je .LBB5_3
movl $1, %edx
callq *__rustc::__rust_dealloc@GOTPCREL(%rip)
.LBB5_3:
movq %r15, (%r14)
movq %rbx, 8(%r14)
movq %r14, 8(%rsp)
leaq 8(%rsp), %rax
#APP
#NO_APP
addq $16, %rsp
popq %rbx
popq %r14
popq %r15
retq
It seems only Option<Vec<T>> has this problem, but I'm not sure.