@@ -22,7 +22,7 @@ use std::mem;
2222use std:: ops:: Deref ;
2323
2424use super :: ops:: { self , NonConstOp , Status } ;
25- use super :: qualifs:: { self , CustomEq , HasMutInterior , NeedsNonConstDrop } ;
25+ use super :: qualifs:: { self , CustomEq , HasMutInterior , NeedsDrop , NeedsNonConstDrop } ;
2626use super :: resolver:: FlowSensitiveAnalysis ;
2727use super :: { is_lang_panic_fn, is_lang_special_const_fn, ConstCx , Qualif } ;
2828use crate :: const_eval:: is_unstable_const_fn;
@@ -39,7 +39,8 @@ type QualifResults<'mir, 'tcx, Q> =
3939#[ derive( Default ) ]
4040pub struct Qualifs < ' mir , ' tcx > {
4141 has_mut_interior : Option < QualifResults < ' mir , ' tcx , HasMutInterior > > ,
42- needs_drop : Option < QualifResults < ' mir , ' tcx , NeedsNonConstDrop > > ,
42+ needs_drop : Option < QualifResults < ' mir , ' tcx , NeedsDrop > > ,
43+ needs_non_const_drop : Option < QualifResults < ' mir , ' tcx , NeedsNonConstDrop > > ,
4344 indirectly_mutable : Option < IndirectlyMutableResults < ' mir , ' tcx > > ,
4445}
4546
@@ -80,14 +81,14 @@ impl Qualifs<'mir, 'tcx> {
8081 location : Location ,
8182 ) -> bool {
8283 let ty = ccx. body . local_decls [ local] . ty ;
83- if !NeedsNonConstDrop :: in_any_value_of_ty ( ccx, ty) {
84+ if !NeedsDrop :: in_any_value_of_ty ( ccx, ty) {
8485 return false ;
8586 }
8687
8788 let needs_drop = self . needs_drop . get_or_insert_with ( || {
8889 let ConstCx { tcx, body, .. } = * ccx;
8990
90- FlowSensitiveAnalysis :: new ( NeedsNonConstDrop , ccx)
91+ FlowSensitiveAnalysis :: new ( NeedsDrop , ccx)
9192 . into_engine ( tcx, & body)
9293 . iterate_to_fixpoint ( )
9394 . into_results_cursor ( & body)
@@ -97,6 +98,33 @@ impl Qualifs<'mir, 'tcx> {
9798 needs_drop. get ( ) . contains ( local) || self . indirectly_mutable ( ccx, local, location)
9899 }
99100
101+ /// Returns `true` if `local` is `NeedsNonConstDrop` at the given `Location`.
102+ ///
103+ /// Only updates the cursor if absolutely necessary
104+ pub fn needs_non_const_drop (
105+ & mut self ,
106+ ccx : & ' mir ConstCx < ' mir , ' tcx > ,
107+ local : Local ,
108+ location : Location ,
109+ ) -> bool {
110+ let ty = ccx. body . local_decls [ local] . ty ;
111+ if !NeedsNonConstDrop :: in_any_value_of_ty ( ccx, ty) {
112+ return false ;
113+ }
114+
115+ let needs_non_const_drop = self . needs_non_const_drop . get_or_insert_with ( || {
116+ let ConstCx { tcx, body, .. } = * ccx;
117+
118+ FlowSensitiveAnalysis :: new ( NeedsNonConstDrop , ccx)
119+ . into_engine ( tcx, & body)
120+ . iterate_to_fixpoint ( )
121+ . into_results_cursor ( & body)
122+ } ) ;
123+
124+ needs_non_const_drop. seek_before_primary_effect ( location) ;
125+ needs_non_const_drop. get ( ) . contains ( local) || self . indirectly_mutable ( ccx, local, location)
126+ }
127+
100128 /// Returns `true` if `local` is `HasMutInterior` at the given `Location`.
101129 ///
102130 /// Only updates the cursor if absolutely necessary.
@@ -173,6 +201,7 @@ impl Qualifs<'mir, 'tcx> {
173201
174202 ConstQualifs {
175203 needs_drop : self . needs_drop ( ccx, RETURN_PLACE , return_loc) ,
204+ needs_non_const_drop : self . needs_non_const_drop ( ccx, RETURN_PLACE , return_loc) ,
176205 has_mut_interior : self . has_mut_interior ( ccx, RETURN_PLACE , return_loc) ,
177206 custom_eq,
178207 error_occured,
@@ -999,7 +1028,7 @@ impl Visitor<'tcx> for Checker<'mir, 'tcx> {
9991028 }
10001029
10011030 // Forbid all `Drop` terminators unless the place being dropped is a local with no
1002- // projections that cannot be `NeedsDrop `.
1031+ // projections that cannot be `NeedsNonConstDrop `.
10031032 TerminatorKind :: Drop { place : dropped_place, .. }
10041033 | TerminatorKind :: DropAndReplace { place : dropped_place, .. } => {
10051034 // If we are checking live drops after drop-elaboration, don't emit duplicate
@@ -1019,15 +1048,15 @@ impl Visitor<'tcx> for Checker<'mir, 'tcx> {
10191048 return ;
10201049 }
10211050
1022- let needs_drop = if let Some ( local) = dropped_place. as_local ( ) {
1051+ let needs_non_const_drop = if let Some ( local) = dropped_place. as_local ( ) {
10231052 // Use the span where the local was declared as the span of the drop error.
10241053 err_span = self . body . local_decls [ local] . source_info . span ;
1025- self . qualifs . needs_drop ( self . ccx , local, location)
1054+ self . qualifs . needs_non_const_drop ( self . ccx , local, location)
10261055 } else {
10271056 true
10281057 } ;
10291058
1030- if needs_drop {
1059+ if needs_non_const_drop {
10311060 self . check_op_spanned (
10321061 ops:: LiveDrop { dropped_at : Some ( terminator. source_info . span ) } ,
10331062 err_span,
0 commit comments