|
3 | 3 | use crate::build::{BlockAnd, BlockAndExtension, Builder};
|
4 | 4 | use crate::build::scope::DropKind;
|
5 | 5 | use crate::hair::*;
|
| 6 | +use rustc::hir; |
6 | 7 | use rustc::middle::region;
|
7 | 8 | use rustc::mir::*;
|
8 | 9 |
|
@@ -66,32 +67,46 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
66 | 67 | };
|
67 | 68 | let temp_place = &Place::from(temp);
|
68 | 69 |
|
69 |
| - if !expr_ty.is_never() { |
70 |
| - this.cfg.push( |
71 |
| - block, |
72 |
| - Statement { |
73 |
| - source_info, |
74 |
| - kind: StatementKind::StorageLive(temp), |
75 |
| - }, |
76 |
| - ); |
77 |
| - |
78 |
| - // In constants, `temp_lifetime` is `None` for temporaries that live for the |
79 |
| - // `'static` lifetime. Thus we do not drop these temporaries and simply leak them. |
80 |
| - // This is equivalent to what `let x = &foo();` does in functions. The temporary |
81 |
| - // is lifted to their surrounding scope. In a function that means the temporary lives |
82 |
| - // until just before the function returns. In constants that means it outlives the |
83 |
| - // constant's initialization value computation. Anything outliving a constant |
84 |
| - // must have the `'static` lifetime and live forever. |
85 |
| - // Anything with a shorter lifetime (e.g the `&foo()` in `bar(&foo())` or anything |
86 |
| - // within a block will keep the regular drops just like runtime code. |
87 |
| - if let Some(temp_lifetime) = temp_lifetime { |
88 |
| - this.schedule_drop( |
89 |
| - expr_span, |
90 |
| - temp_lifetime, |
91 |
| - temp, |
92 |
| - expr_ty, |
93 |
| - DropKind::Storage, |
| 70 | + match expr.kind { |
| 71 | + // Don't bother with StorageLive and Dead for these temporaries, |
| 72 | + // they are never assigned. |
| 73 | + ExprKind::Break { .. } | |
| 74 | + ExprKind::Continue { .. } | |
| 75 | + ExprKind::Return { .. } => (), |
| 76 | + ExprKind::Block { |
| 77 | + body: hir::Block { expr: None, targeted_by_break: false, .. } |
| 78 | + } if expr_ty.is_never() => (), |
| 79 | + _ => { |
| 80 | + this.cfg.push( |
| 81 | + block, |
| 82 | + Statement { |
| 83 | + source_info, |
| 84 | + kind: StatementKind::StorageLive(temp), |
| 85 | + }, |
94 | 86 | );
|
| 87 | + |
| 88 | + // In constants, `temp_lifetime` is `None` for temporaries that |
| 89 | + // live for the `'static` lifetime. Thus we do not drop these |
| 90 | + // temporaries and simply leak them. |
| 91 | + // This is equivalent to what `let x = &foo();` does in |
| 92 | + // functions. The temporary is lifted to their surrounding |
| 93 | + // scope. In a function that means the temporary lives until |
| 94 | + // just before the function returns. In constants that means it |
| 95 | + // outlives the constant's initialization value computation. |
| 96 | + // Anything outliving a constant must have the `'static` |
| 97 | + // lifetime and live forever. |
| 98 | + // Anything with a shorter lifetime (e.g the `&foo()` in |
| 99 | + // `bar(&foo())` or anything within a block will keep the |
| 100 | + // regular drops just like runtime code. |
| 101 | + if let Some(temp_lifetime) = temp_lifetime { |
| 102 | + this.schedule_drop( |
| 103 | + expr_span, |
| 104 | + temp_lifetime, |
| 105 | + temp, |
| 106 | + expr_ty, |
| 107 | + DropKind::Storage, |
| 108 | + ); |
| 109 | + } |
95 | 110 | }
|
96 | 111 | }
|
97 | 112 |
|
|
0 commit comments