diff --git a/src/librustc_mir/build/expr/as_temp.rs b/src/librustc_mir/build/expr/as_temp.rs index 8f50a1e9a21b9..2db9fb9cb99f4 100644 --- a/src/librustc_mir/build/expr/as_temp.rs +++ b/src/librustc_mir/build/expr/as_temp.rs @@ -85,9 +85,15 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { unpack!(block = this.into(&Place::Local(temp), block, expr)); - // In constants, temp_lifetime is None. We should not need to drop - // anything because no values with a destructor can be created in - // a constant at this time, even if the type may need dropping. + // In constants, temp_lifetime is None for temporaries that live for the + // 'static lifetime. Thus we do not drop these temporaries and simply leak them. + // This is equivalent to what `let x = &foo();` does in functions. The temporary + // is lifted to their surrounding scope. In a function that means the temporary lives + // until just before the function returns. In constants that means it outlives the + // constant's initialization value computation. Anything outliving a constant + // must have the `'static` lifetime and live forever. + // Anything with a shorter lifetime (e.g the `&foo()` in `bar(&foo())` or anything + // within a block will keep the regular drops just like runtime code. if let Some(temp_lifetime) = temp_lifetime { this.schedule_drop_storage_and_value( expr_span,