Skip to content

Commit d23d87c

Browse files
committed
Stop generating code in mem::forget
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...
1 parent 7efc097 commit d23d87c

File tree

3 files changed

+36
-3
lines changed

3 files changed

+36
-3
lines changed

library/core/src/intrinsics.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -838,8 +838,11 @@ extern "rust-intrinsic" {
838838

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

845848
/// Reinterprets the bits of a value of one type as another type.

library/core/src/mem/mod.rs

+10-1
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,16 @@ pub use crate::intrinsics::transmute;
141141
#[rustc_const_stable(feature = "const_forget", since = "1.46.0")]
142142
#[stable(feature = "rust1", since = "1.0.0")]
143143
pub const fn forget<T>(t: T) {
144-
let _ = ManuallyDrop::new(t);
144+
// Ideally this would just be
145+
// ```
146+
// let _ = ManuallyDrop::new(t);
147+
// ```
148+
// but as of 2020-12-12 that actually codegens the construction of the type,
149+
// which there's no reason to do. Please switch it back if things have changed and
150+
// the forget-is-nop codegen test confirms the intrinsic is no longer needed here.
151+
152+
// SAFETY: Forgetting is safe; it's just the intrinsic that isn't.
153+
unsafe { intrinsics::forget(t) }
145154
}
146155

147156
/// Like [`forget`], but also accepts unsized values.

src/test/codegen/forget-is-nop.rs

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// compile-flags: -C opt-level=0
2+
3+
#![crate_type = "lib"]
4+
5+
// CHECK-LABEL: mem6forget{{.+}}[100 x %"std::string::String"]*
6+
// CHECK-NOT: alloca
7+
// CHECK-NOT: memcpy
8+
// CHECK: ret
9+
10+
// CHECK-LABEL: mem6forget{{.+}}[100 x i64]*
11+
// CHECK-NOT: alloca
12+
// CHECK-NOT: memcpy
13+
// CHECK: ret
14+
15+
pub fn forget_large_copy_type(whatever: [i64; 100]) {
16+
std::mem::forget(whatever)
17+
}
18+
19+
pub fn forget_large_drop_type(whatever: [String; 100]) {
20+
std::mem::forget(whatever)
21+
}

0 commit comments

Comments
 (0)