An impl does not add anything to SomeStruct
's in-memory representation*. An impl has the exact same runtime overhead as it's constituent function definitions: a trait impl with no function definitions in it, such as an impl of Send
, is pure compiler metadata with no runtime representation at all. These compile down to the same asm, only the names are changed.
With a trait
pub struct SomeStruct {
data: usize,
}
impl From<SomeStruct> for usize {
fn from(a: SomeStruct) -> usize {
a.data
}
}
fn main() {
let data: usize = From::from(SomeStruct{data: 3});
println!("{}", data);
}
With a bare function
pub struct SomeStruct {
data: usize,
}
fn from(a: SomeStruct) -> usize {
a.data
}
fn main() {
let data: usize = from(SomeStruct{data: 3});
println!("{}", data);
}
The difference between the generated assembler files
Generated using rustc --emit asm
and diff
.
2,3c2,3
< .file "test_bare_fn.0.rs"
< .section .text._ZN4from20h21c98f259508b997iaaE,"ax",@progbits
---
> .file "test_trait_fn.0.rs"
> .section ".text._ZN28usize.From$LT$SomeStruct$GT$4from20h0cc7013da25f51e9jaaE","ax",@progbits
5,6c5,6
< .type _ZN4from20h21c98f259508b997iaaE,@function
< _ZN4from20h21c98f259508b997iaaE:
---
> .type _ZN28usize.From$LT$SomeStruct$GT$4from20h0cc7013da25f51e9jaaE,@function
> _ZN28usize.From$LT$SomeStruct$GT$4from20h0cc7013da25f51e9jaaE:
23c23
< .size _ZN4from20h21c98f259508b997iaaE, .Ltmp1-_ZN4from20h21c98f259508b997iaaE
---
> .size _ZN28usize.From$LT$SomeStruct$GT$4from20h0cc7013da25f51e9jaaE, .Ltmp1-_ZN28usize.From$LT$SomeStruct$GT$4from20h0cc7013da25f51e9jaaE
26c26
< .section .text._ZN4main20hc363dbfca27efb45raaE,"ax",@progbits
---
> .section .text._ZN4main20h5cc8e894ab3a62d8waaE,"ax",@progbits
28,29c28,29
< .type _ZN4main20hc363dbfca27efb45raaE,@function
< _ZN4main20hc363dbfca27efb45raaE:
---
> .type _ZN4main20h5cc8e894ab3a62d8waaE,@function
> _ZN4main20h5cc8e894ab3a62d8waaE:
41,42c41,42
< movq const894(%rip), %rdi
< callq _ZN4from20h21c98f259508b997iaaE
---
> movq const903(%rip), %rdi
> callq _ZN28usize.From$LT$SomeStruct$GT$4from20h0cc7013da25f51e9jaaE
46c46
< movq _ZN4main15__STATIC_FMTSTR20h184a1ba70fe95744KaaE(%rip), %rax
---
> movq _ZN4main15__STATIC_FMTSTR20h58daeaf08cc7ff5ePaaE(%rip), %rax
48c48
< movq _ZN4main15__STATIC_FMTSTR20h184a1ba70fe95744KaaE+8(%rip), %rax
---
> movq _ZN4main15__STATIC_FMTSTR20h58daeaf08cc7ff5ePaaE+8(%rip), %rax
60c60
< callq _ZN3fmt24ArgumentV1$LT$$u27$a$GT$3new20h4867565462692555336E
---
> callq _ZN3fmt24ArgumentV1$LT$$u27$a$GT$3new21h10416708861696835008E
73c73
< .size _ZN4main20hc363dbfca27efb45raaE, .Ltmp3-_ZN4main20hc363dbfca27efb45raaE
---
> .size _ZN4main20h5cc8e894ab3a62d8waaE, .Ltmp3-_ZN4main20h5cc8e894ab3a62d8waaE
86c86
< movq const1000(%rip), %rcx
---
> movq const1009(%rip), %rcx
88c88
< movq const1000+8(%rip), %rcx
---
> movq const1009+8(%rip), %rcx
99c99
< .section ".text._ZN3fmt24ArgumentV1$LT$$u27$a$GT$3new20h4867565462692555336E","ax",@progbits
---
> .section ".text._ZN3fmt24ArgumentV1$LT$$u27$a$GT$3new21h10416708861696835008E","ax",@progbits
101,102c101,102
< .type _ZN3fmt24ArgumentV1$LT$$u27$a$GT$3new20h4867565462692555336E,@function
< _ZN3fmt24ArgumentV1$LT$$u27$a$GT$3new20h4867565462692555336E:
---
> .type _ZN3fmt24ArgumentV1$LT$$u27$a$GT$3new21h10416708861696835008E,@function
> _ZN3fmt24ArgumentV1$LT$$u27$a$GT$3new21h10416708861696835008E:
124c124
< .size _ZN3fmt24ArgumentV1$LT$$u27$a$GT$3new20h4867565462692555336E, .Ltmp6-_ZN3fmt24ArgumentV1$LT$$u27$a$GT$3new20h4867565462692555336E
---
> .size _ZN3fmt24ArgumentV1$LT$$u27$a$GT$3new21h10416708861696835008E, .Ltmp6-_ZN3fmt24ArgumentV1$LT$$u27$a$GT$3new21h10416708861696835008E
143c143
< leaq _ZN4main20hc363dbfca27efb45raaE(%rip), %rax
---
> leaq _ZN4main20h5cc8e894ab3a62d8waaE(%rip), %rax
157,158c157,158
< .type const894,@object
< .section .rodata.const894,"aM",@progbits,8
---
> .type const903,@object
> .section .rodata.const903,"aM",@progbits,8
160c160
< const894:
---
> const903:
162c162
< .size const894, 8
---
> .size const903, 8
164,165c164,165
< .type const1000,@object
< .section .rodata.const1000,"aM",@progbits,16
---
> .type const1009,@object
> .section .rodata.const1009,"aM",@progbits,16
167c167
< const1000:
---
> const1009:
169c169
< .size const1000, 16
---
> .size const1009, 16
171,178c171,178
< .type str1001,@object
< .section .rodata.str1001,"a",@progbits
< str1001:
< .size str1001, 0
<
< .type str1002,@object
< .section .rodata.str1002,"a",@progbits
< str1002:
---
> .type str1010,@object
> .section .rodata.str1010,"a",@progbits
> str1010:
> .size str1010, 0
>
> .type str1011,@object
> .section .rodata.str1011,"a",@progbits
> str1011:
180c180
< .size str1002, 1
---
> .size str1011, 1
182,183c182,183
< .type ref1003,@object
< .section .data.rel.ro.local.ref1003,"aw",@progbits
---
> .type ref1012,@object
> .section .data.rel.ro.local.ref1012,"aw",@progbits
185,186c185,186
< ref1003:
< .quad str1001
---
> ref1012:
> .quad str1010
188c188
< .quad str1002
---
> .quad str1011
190c190
< .size ref1003, 32
---
> .size ref1012, 32
192,193c192,193
< .type _ZN4main15__STATIC_FMTSTR20h184a1ba70fe95744KaaE,@object
< .section .data.rel.ro.local._ZN4main15__STATIC_FMTSTR20h184a1ba70fe95744KaaE,"aw",@progbits
---
> .type _ZN4main15__STATIC_FMTSTR20h58daeaf08cc7ff5ePaaE,@object
> .section .data.rel.ro.local._ZN4main15__STATIC_FMTSTR20h58daeaf08cc7ff5ePaaE,"aw",@progbits
195,196c195,196
< _ZN4main15__STATIC_FMTSTR20h184a1ba70fe95744KaaE:
< .quad ref1003
---
> _ZN4main15__STATIC_FMTSTR20h58daeaf08cc7ff5ePaaE:
> .quad ref1012
198c198
< .size _ZN4main15__STATIC_FMTSTR20h184a1ba70fe95744KaaE, 16
---
> .size _ZN4main15__STATIC_FMTSTR20h58daeaf08cc7ff5ePaaE, 16
200,201c200,201
< .type const1013,@object
< .section .data.rel.ro.const1013,"aw",@progbits
---
> .type const1022,@object
> .section .data.rel.ro.const1022,"aw",@progbits
203c203
< const1013:
---
> const1022:
205c205
< .size const1013, 8
---
> .size const1022, 8
* The built-in Drop
trait magically adds a hidden "drop flag" to anything that impl's it. The core team is planning to move these flags into a bit field on the stack. This is the only exception.