Skip to content

Instantly share code, notes, and snippets.

@colin-kiegel
Last active August 8, 2016 20:26
Show Gist options
  • Save colin-kiegel/85d6659da34f34e9e133fc0d9767152f to your computer and use it in GitHub Desktop.
Save colin-kiegel/85d6659da34f34e9e133fc0d9767152f to your computer and use it in GitHub Desktop.
Should builder methods use `mut self` or `&mut self`?
#[derive(Debug, Default)]
struct Channel {
special_info: i32
}
impl Channel {
fn special_info<VALUE: Into<i32>>(mut self, value: VALUE) -> Self {
self.special_info = value.into();
self
}
fn build(mut self) -> Self {
Channel {
special_info: self.special_info
}
}
}
/// consume variables with black_box to avoid optimization of trivial code.
#[inline(never)]
fn black_box(_x: Channel) {
}
fn main() {
let ch = Channel::default().special_info(42).build();
black_box(ch);
}
.text
.file "rust_out.cgu-0.rs"
.section .text._ZN8rust_out4main17h4bd17b1d5c1469adE,"ax",@progbits
.p2align 4, 0x90
.type _ZN8rust_out4main17h4bd17b1d5c1469adE,@function
_ZN8rust_out4main17h4bd17b1d5c1469adE:
.cfi_startproc
retq
.Lfunc_end0:
.size _ZN8rust_out4main17h4bd17b1d5c1469adE, .Lfunc_end0-_ZN8rust_out4main17h4bd17b1d5c1469adE
.cfi_endproc
.section .text.main,"ax",@progbits
.globl main
.p2align 4, 0x90
.type main,@function
main:
.cfi_startproc
movq %rsi, %rax
movq %rdi, %rcx
leaq _ZN8rust_out4main17h4bd17b1d5c1469adE(%rip), %rdi
movq %rcx, %rsi
movq %rax, %rdx
jmp _ZN3std2rt10lang_start17hfe9ab243c60ffb9bE@PLT
.Lfunc_end1:
.size main, .Lfunc_end1-main
.cfi_endproc
.section ".note.GNU-stack","",@progbits
; ModuleID = 'rust_out.cgu-0.rs'
source_filename = "rust_out.cgu-0.rs"
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
; Function Attrs: norecurse nounwind readnone uwtable
define internal void @_ZN8rust_out4main17h4bd17b1d5c1469adE() unnamed_addr #0 {
entry-block:
ret void
}
define i64 @main(i64, i8**) unnamed_addr {
top:
%2 = tail call i64 @_ZN3std2rt10lang_start17hfe9ab243c60ffb9bE(i8* bitcast (void ()* @_ZN8rust_out4main17h4bd17b1d5c1469adE to i8*), i64 %0, i8** %1)
ret i64 %2
}
declare i64 @_ZN3std2rt10lang_start17hfe9ab243c60ffb9bE(i8*, i64, i8**) unnamed_addr
attributes #0 = { norecurse nounwind readnone uwtable }
!llvm.module.flags = !{!0}
!0 = !{i32 1, !"PIE Level", i32 2}
fn <Channel as std::default::Default>::default() -> Channel {
let mut tmp0: i32;
bb0: {
tmp0 = <i32 as std::default::Default>::default() -> bb1; // scope 0 at <anon>:3:5: 3:22
}
bb1: {
return = Channel { special_info: tmp0 }; // scope 0 at <anon>:1:17: 1:24
return; // scope 0 at <anon>:1:17: 1:24
}
}
fn <Channel as std::fmt::Debug>::fmt(arg0: &Channel, arg1: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
scope 1 {
let var0: &Channel; // "self" in scope 1 at <anon>:1:10: 1:15
let var1: &mut std::fmt::Formatter<'_>; // "__arg_0" in scope 1 at <anon>:1:10: 1:15
scope 2 {
let var2: &i32; // "__self_0_0" in scope 2 at <anon>:3:5: 3:22
scope 3 {
let mut var3: std::fmt::DebugStruct<'_, '_>; // "builder" in scope 3 at <anon>:1:1: 1:1
}
}
}
let mut tmp0: &mut std::fmt::Formatter<'_>;
let mut tmp1: &str;
let mut tmp2: &'static str;
let mut tmp3: &mut std::fmt::DebugStruct<'_, '_>;
let mut tmp4: &mut std::fmt::DebugStruct<'_, '_>;
let mut tmp5: &str;
let mut tmp6: &'static str;
let mut tmp7: &std::fmt::Debug;
let mut tmp8: &&i32;
let mut tmp9: &&i32;
let mut tmp10: &i32;
let mut tmp11: &mut std::fmt::DebugStruct<'_, '_>;
bb0: {
var0 = arg0; // scope 0 at <anon>:1:10: 1:15
var1 = arg1; // scope 0 at <anon>:1:10: 1:15
var2 = &((*var0).0: i32); // scope 1 at <anon>:3:5: 3:22
goto -> bb1; // scope 1 at <anon>:1:10: 1:15
}
bb1: {
tmp0 = &mut (*var1); // scope 2 at <anon>:1:10: 1:15
tmp2 = const "Channel"; // scope 2 at <anon>:1:10: 1:15
tmp1 = &(*tmp2); // scope 2 at <anon>:1:10: 1:15
var3 = std::fmt::Formatter<'_>::debug_struct(tmp0, tmp1) -> bb3; // scope 2 at <anon>:1:10: 1:15
}
bb2: {
return; // scope 1 at <anon>:1:10: 1:15
}
bb3: {
tmp4 = &mut var3; // scope 3 at <anon>:1:10: 1:15
tmp6 = const "special_info"; // scope 3 at <anon>:3:5: 3:22
tmp5 = &(*tmp6); // scope 3 at <anon>:3:5: 3:22
tmp10 = &(*var2); // scope 3 at <anon>:3:5: 3:22
tmp9 = &tmp10; // scope 3 at <anon>:3:5: 3:22
tmp8 = &(*tmp9); // scope 3 at <anon>:3:5: 3:22
tmp7 = tmp8 as &std::fmt::Debug (Unsize); // scope 3 at <anon>:3:5: 3:22
tmp3 = std::fmt::DebugStruct<'_, '_>::field(tmp4, tmp5, tmp7) -> bb4; // scope 3 at <anon>:1:10: 1:15
}
bb4: {
tmp11 = &mut var3; // scope 3 at <anon>:1:10: 1:15
return = std::fmt::DebugStruct<'_, '_>::finish(tmp11) -> bb2; // scope 3 at <anon>:1:10: 1:15
}
}
fn Channel::build(arg0: Channel) -> Channel {
scope 1 {
let mut var0: Channel; // "self" in scope 1 at <anon>:12:14: 12:22
}
let mut tmp0: i32;
bb0: {
var0 = arg0; // scope 0 at <anon>:12:14: 12:22
tmp0 = (var0.0: i32); // scope 1 at <anon>:14:27: 14:44
return = Channel { special_info: tmp0 }; // scope 1 at <anon>:13:9: 15:10
goto -> bb1; // scope 1 at <anon>:12:5: 16:6
}
bb1: {
return; // scope 1 at <anon>:12:5: 16:6
}
}
fn Channel::special_info(arg0: Channel, arg1: VALUE) -> Channel {
scope 1 {
let mut var0: Channel; // "self" in scope 1 at <anon>:7:39: 7:47
let var1: VALUE; // "value" in scope 1 at <anon>:7:49: 7:54
}
let mut tmp0: i32;
let mut tmp1: VALUE;
let mut tmp2: ();
let mut tmp3: Channel;
bb0: {
var0 = arg0; // scope 0 at <anon>:7:39: 7:47
var1 = arg1; // scope 0 at <anon>:7:49: 7:54
tmp1 = var1; // scope 1 at <anon>:8:29: 8:34
tmp0 = <VALUE as std::convert::Into<i32>>::into(tmp1) -> [return: bb5, unwind: bb4]; // scope 1 at <anon>:8:29: 8:41
}
bb1: {
resume; // scope 0 at <anon>:7:5: 10:6
}
bb2: {
drop(var1) -> bb1; // scope 0 at <anon>:7:49: 7:54
}
bb3: {
drop(arg1) -> bb2; // scope 0 at <anon>:7:49: 7:54
}
bb4: {
drop(tmp1) -> bb3; // scope 1 at <anon>:8:29: 8:34
}
bb5: {
(var0.0: i32) = tmp0; // scope 1 at <anon>:8:9: 8:41
drop(tmp1) -> [return: bb6, unwind: bb3]; // scope 1 at <anon>:8:29: 8:34
}
bb6: {
tmp3 = var0; // scope 1 at <anon>:9:9: 9:13
return = tmp3; // scope 1 at <anon>:9:9: 9:13
drop(arg1) -> [return: bb7, unwind: bb2]; // scope 0 at <anon>:7:49: 7:54
}
bb7: {
drop(var1) -> bb8; // scope 0 at <anon>:7:49: 7:54
}
bb8: {
return; // scope 1 at <anon>:7:5: 10:6
}
}
fn black_box(arg0: Channel) -> () {
scope 1 {
let var0: Channel; // "_x" in scope 1 at <anon>:21:14: 21:16
}
bb0: {
var0 = arg0; // scope 0 at <anon>:21:14: 21:16
return = (); // scope 1 at <anon>:21:27: 22:2
goto -> bb1; // scope 1 at <anon>:21:1: 22:2
}
bb1: {
return; // scope 1 at <anon>:21:1: 22:2
}
}
fn main() -> () {
scope 1 {
let var0: Channel; // "ch" in scope 1 at <anon>:25:9: 25:11
}
let mut tmp0: Channel;
let mut tmp1: Channel;
let mut tmp2: ();
let mut tmp3: Channel;
bb0: {
tmp1 = <Channel as std::default::Default>::default() -> bb1; // scope 0 at <anon>:25:14: 25:32
}
bb1: {
tmp0 = Channel::special_info::<i32>(tmp1, const 42i32) -> bb2; // scope 0 at <anon>:25:14: 25:49
}
bb2: {
var0 = Channel::build(tmp0) -> bb3; // scope 0 at <anon>:25:14: 25:57
}
bb3: {
tmp3 = var0; // scope 1 at <anon>:26:15: 26:17
tmp2 = black_box(tmp3) -> bb4; // scope 1 at <anon>:26:5: 26:18
}
bb4: {
return = (); // scope 1 at <anon>:24:11: 27:2
return; // scope 0 at <anon>:24:1: 27:2
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment