I can't speak authoritatively to the overall compilation performance, but this is definitely not true: (Curve<f32>)
is just the fields of Curve32
, and Curve32
is not a generic type any more than any other struct without type parameters.
To check and demonstrate this, I wrote the following test code in a library package:
pub struct Example(Vec<f32>);
impl Example {
pub fn new() -> Self {
Self(Vec::new())
}
pub fn push(&mut self, x: f32) {
self.0.push(x)
}
}
And then compiled it with cargo rustc --lib --release -- --emit=asm
, producing the following assembly file (for x86_64-apple-darwin
):
.section __TEXT,__text,regular,pure_instructions
.macosx_version_min 10, 7
.p2align 4, 0x90
__ZN5alloc7raw_vec11finish_grow17h2cec18ebe4b8467fE:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset %rbp, -16
movq %rsp, %rbp
.cfi_def_cfa_register %rbp
pushq %r15
pushq %r14
pushq %rbx
pushq %rax
.cfi_offset %rbx, -40
.cfi_offset %r14, -32
.cfi_offset %r15, -24
movq %rsi, %r14
movq %rdi, %rbx
testq %rdx, %rdx
je LBB0_5
movq %rdx, %r15
cmpq $0, 16(%rcx)
je LBB0_7
movq 8(%rcx), %rsi
testq %rsi, %rsi
je LBB0_7
movq (%rcx), %rdi
movq %r15, %rdx
movq %r14, %rcx
callq ___rust_realloc
testq %rax, %rax
jne LBB0_11
LBB0_4:
movq %r14, 8(%rbx)
movq %r15, 16(%rbx)
jmp LBB0_6
LBB0_7:
testq %r14, %r14
je LBB0_8
movq %r14, %rdi
movq %r15, %rsi
callq ___rust_alloc
testq %rax, %rax
je LBB0_4
LBB0_11:
movq %rax, 8(%rbx)
movq %r14, 16(%rbx)
xorl %eax, %eax
jmp LBB0_12
LBB0_5:
movq %r14, 8(%rbx)
movq $0, 16(%rbx)
LBB0_6:
movl $1, %eax
LBB0_12:
movq %rax, (%rbx)
addq $8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
LBB0_8:
movq %r15, %rax
testq %rax, %rax
jne LBB0_11
jmp LBB0_4
.cfi_endproc
.p2align 4, 0x90
__ZN5alloc7raw_vec19RawVec$LT$T$C$A$GT$16reserve_for_push17hd9ce4f6e52de7bc4E:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset %rbp, -16
movq %rsp, %rbp
.cfi_def_cfa_register %rbp
pushq %r14
pushq %rbx
subq $48, %rsp
.cfi_offset %rbx, -32
.cfi_offset %r14, -24
incq %rsi
je LBB1_10
movq %rdi, %rbx
movq (%rdi), %rax
leaq (%rax,%rax), %rcx
cmpq %rsi, %rcx
cmovaq %rcx, %rsi
cmpq $5, %rsi
movl $4, %r14d
cmovaeq %rsi, %r14
xorl %edx, %edx
movq %r14, %rcx
shrq $61, %rcx
sete %dl
leaq (,%r14,4), %rsi
shlq $2, %rdx
testq %rax, %rax
je LBB1_3
movq 8(%rbx), %rcx
shlq $2, %rax
movq %rcx, -40(%rbp)
movq %rax, -32(%rbp)
movq $4, -24(%rbp)
jmp LBB1_4
LBB1_3:
movq $0, -24(%rbp)
LBB1_4:
leaq -64(%rbp), %rdi
leaq -40(%rbp), %rcx
callq __ZN5alloc7raw_vec11finish_grow17h2cec18ebe4b8467fE
cmpq $0, -64(%rbp)
movq -56(%rbp), %rdi
je LBB1_5
movq -48(%rbp), %rsi
movabsq $-9223372036854775807, %rax
cmpq %rax, %rsi
je LBB1_6
testq %rsi, %rsi
jne LBB1_9
LBB1_10:
callq __ZN5alloc7raw_vec17capacity_overflow17h833df1bab8a6c0cbE
LBB1_5:
movq %rdi, 8(%rbx)
movq %r14, (%rbx)
LBB1_6:
addq $48, %rsp
popq %rbx
popq %r14
popq %rbp
retq
LBB1_9:
callq __ZN5alloc5alloc18handle_alloc_error17h7841226fad19e9beE
.cfi_endproc
.globl __ZN10scratchpad7Example3new17ha3cb64f0783a7025E
.p2align 4, 0x90
__ZN10scratchpad7Example3new17ha3cb64f0783a7025E:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset %rbp, -16
movq %rsp, %rbp
.cfi_def_cfa_register %rbp
movq %rdi, %rax
movq $0, (%rdi)
movq $4, 8(%rdi)
movq $0, 16(%rdi)
popq %rbp
retq
.cfi_endproc
.globl __ZN10scratchpad7Example4push17hbf1de231eeeb6362E
.p2align 4, 0x90
__ZN10scratchpad7Example4push17hbf1de231eeeb6362E:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset %rbp, -16
movq %rsp, %rbp
.cfi_def_cfa_register %rbp
pushq %rbx
pushq %rax
.cfi_offset %rbx, -24
movq %rdi, %rbx
movq 16(%rdi), %rsi
cmpq (%rdi), %rsi
jne LBB3_2
movq %rbx, %rdi
movss %xmm0, -12(%rbp)
callq __ZN5alloc7raw_vec19RawVec$LT$T$C$A$GT$16reserve_for_push17hd9ce4f6e52de7bc4E
movss -12(%rbp), %xmm0
movq 16(%rbx), %rsi
LBB3_2:
movq 8(%rbx), %rax
movss %xmm0, (%rax,%rsi,4)
incq %rsi
movq %rsi, 16(%rbx)
addq $8, %rsp
popq %rbx
popq %rbp
retq
.cfi_endproc
.subsections_via_symbols
This contains code for creating and (re)allocating the Vec<f32>
, so monomorphization and code generation has happened at the library compilation stage.
If the type were generic, we would not see any of this machine code; it would only exist as MIR in the .rlib
output, and be turned into machine code only when it is used concretely in some other crate.