Skip to content

Commit

Permalink
Stop generating code in mem::forget
Browse files Browse the repository at this point in the history
Yes, the optimizer can remove it, but there's really no reason to bother emitting it in the first place.  Not to mention that it all gets run in debug mode...
  • Loading branch information
scottmcm committed Dec 12, 2020
1 parent 7efc097 commit d23d87c
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 3 deletions.
7 changes: 5 additions & 2 deletions library/core/src/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -838,8 +838,11 @@ extern "rust-intrinsic" {

/// Moves a value out of scope without running drop glue.
///
/// This exists solely for [`mem::forget_unsized`]; normal `forget` uses
/// `ManuallyDrop` instead.
/// This is only strictly needed for [`mem::forget_unsized`]; normal [`mem::forget`]
/// compiles fine just using `ManuallyDrop` instead.
///
/// As this does literally nothing, it's trivially const-safe.
#[rustc_const_stable(feature = "const_forget_intrinsic", since = "1.50")]
pub fn forget<T: ?Sized>(_: T);

/// Reinterprets the bits of a value of one type as another type.
Expand Down
11 changes: 10 additions & 1 deletion library/core/src/mem/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,16 @@ pub use crate::intrinsics::transmute;
#[rustc_const_stable(feature = "const_forget", since = "1.46.0")]
#[stable(feature = "rust1", since = "1.0.0")]
pub const fn forget<T>(t: T) {
let _ = ManuallyDrop::new(t);
// Ideally this would just be
// ```
// let _ = ManuallyDrop::new(t);
// ```
// but as of 2020-12-12 that actually codegens the construction of the type,
// which there's no reason to do. Please switch it back if things have changed and
// the forget-is-nop codegen test confirms the intrinsic is no longer needed here.

// SAFETY: Forgetting is safe; it's just the intrinsic that isn't.
unsafe { intrinsics::forget(t) }
}

/// Like [`forget`], but also accepts unsized values.
Expand Down
21 changes: 21 additions & 0 deletions src/test/codegen/forget-is-nop.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// compile-flags: -C opt-level=0

#![crate_type = "lib"]

// CHECK-LABEL: mem6forget{{.+}}[100 x %"std::string::String"]*
// CHECK-NOT: alloca
// CHECK-NOT: memcpy
// CHECK: ret

// CHECK-LABEL: mem6forget{{.+}}[100 x i64]*
// CHECK-NOT: alloca
// CHECK-NOT: memcpy
// CHECK: ret

pub fn forget_large_copy_type(whatever: [i64; 100]) {
std::mem::forget(whatever)
}

pub fn forget_large_drop_type(whatever: [String; 100]) {
std::mem::forget(whatever)
}

0 comments on commit d23d87c

Please sign in to comment.