@@ -62,12 +62,12 @@ pub trait Qualif {
62
62
/// It also determines the `Qualif`s for primitive types.
63
63
fn in_any_value_of_ty < ' tcx > ( cx : & ConstCx < ' _ , ' tcx > , ty : Ty < ' tcx > ) -> bool ;
64
64
65
- /// Returns `true` if the `Qualif` is structural in an ADT's fields, i.e. that we may
66
- /// recurse into an operand if we know what it is .
65
+ /// Returns `true` if the `Qualif` is structural in an ADT's fields, i.e. if we may
66
+ /// recurse into an operand *value* to determine whether it has this `Qualif` .
67
67
///
68
68
/// If this returns false, `in_any_value_of_ty` will be invoked to determine the
69
69
/// final qualif for this ADT.
70
- fn is_structural_in_adt < ' tcx > ( cx : & ConstCx < ' _ , ' tcx > , adt : AdtDef < ' tcx > ) -> bool ;
70
+ fn is_structural_in_adt_value < ' tcx > ( cx : & ConstCx < ' _ , ' tcx > , adt : AdtDef < ' tcx > ) -> bool ;
71
71
}
72
72
73
73
/// Constant containing interior mutability (`UnsafeCell<T>`).
@@ -123,7 +123,7 @@ impl Qualif for HasMutInterior {
123
123
!errors. is_empty ( )
124
124
}
125
125
126
- fn is_structural_in_adt < ' tcx > ( _cx : & ConstCx < ' _ , ' tcx > , adt : AdtDef < ' tcx > ) -> bool {
126
+ fn is_structural_in_adt_value < ' tcx > ( _cx : & ConstCx < ' _ , ' tcx > , adt : AdtDef < ' tcx > ) -> bool {
127
127
// Exactly one type, `UnsafeCell`, has the `HasMutInterior` qualif inherently.
128
128
// It arises structurally for all other types.
129
129
!adt. is_unsafe_cell ( )
@@ -140,6 +140,7 @@ pub struct NeedsDrop;
140
140
impl Qualif for NeedsDrop {
141
141
const ANALYSIS_NAME : & ' static str = "flow_needs_drop" ;
142
142
const IS_CLEARED_ON_MOVE : bool = true ;
143
+ const ALLOW_PROMOTED : bool = true ;
143
144
144
145
fn in_qualifs ( qualifs : & ConstQualifs ) -> bool {
145
146
qualifs. needs_drop
@@ -149,7 +150,7 @@ impl Qualif for NeedsDrop {
149
150
ty. needs_drop ( cx. tcx , cx. typing_env )
150
151
}
151
152
152
- fn is_structural_in_adt < ' tcx > ( cx : & ConstCx < ' _ , ' tcx > , adt : AdtDef < ' tcx > ) -> bool {
153
+ fn is_structural_in_adt_value < ' tcx > ( cx : & ConstCx < ' _ , ' tcx > , adt : AdtDef < ' tcx > ) -> bool {
153
154
!adt. has_dtor ( cx. tcx )
154
155
}
155
156
}
@@ -179,34 +180,30 @@ impl Qualif for NeedsNonConstDrop {
179
180
// that the components of this type are also `~const Destruct`. This
180
181
// amounts to verifying that there are no values in this ADT that may have
181
182
// a non-const drop.
182
- if cx. tcx . features ( ) . const_trait_impl ( ) {
183
- let destruct_def_id = cx. tcx . require_lang_item ( LangItem :: Destruct , Some ( cx. body . span ) ) ;
184
- let infcx =
185
- cx. tcx . infer_ctxt ( ) . build ( TypingMode :: from_param_env ( cx. typing_env . param_env ) ) ;
186
- let ocx = ObligationCtxt :: new ( & infcx) ;
187
- ocx. register_obligation ( Obligation :: new (
188
- cx. tcx ,
189
- ObligationCause :: misc ( cx. body . span , cx. def_id ( ) ) ,
190
- cx. typing_env . param_env ,
191
- ty:: Binder :: dummy ( ty:: TraitRef :: new ( cx. tcx , destruct_def_id, [ ty] ) )
192
- . to_host_effect_clause ( cx. tcx , match cx. const_kind ( ) {
193
- rustc_hir:: ConstContext :: ConstFn => ty:: BoundConstness :: Maybe ,
194
- rustc_hir:: ConstContext :: Static ( _)
195
- | rustc_hir:: ConstContext :: Const { .. } => ty:: BoundConstness :: Const ,
196
- } ) ,
197
- ) ) ;
198
- !ocx. select_all_or_error ( ) . is_empty ( )
199
- } else {
200
- NeedsDrop :: in_any_value_of_ty ( cx, ty)
201
- }
183
+ let destruct_def_id = cx. tcx . require_lang_item ( LangItem :: Destruct , Some ( cx. body . span ) ) ;
184
+ let infcx = cx. tcx . infer_ctxt ( ) . build ( TypingMode :: from_param_env ( cx. typing_env . param_env ) ) ;
185
+ let ocx = ObligationCtxt :: new ( & infcx) ;
186
+ ocx. register_obligation ( Obligation :: new (
187
+ cx. tcx ,
188
+ ObligationCause :: misc ( cx. body . span , cx. def_id ( ) ) ,
189
+ cx. typing_env . param_env ,
190
+ ty:: Binder :: dummy ( ty:: TraitRef :: new ( cx. tcx , destruct_def_id, [ ty] ) )
191
+ . to_host_effect_clause ( cx. tcx , match cx. const_kind ( ) {
192
+ rustc_hir:: ConstContext :: ConstFn => ty:: BoundConstness :: Maybe ,
193
+ rustc_hir:: ConstContext :: Static ( _) | rustc_hir:: ConstContext :: Const { .. } => {
194
+ ty:: BoundConstness :: Const
195
+ }
196
+ } ) ,
197
+ ) ) ;
198
+ !ocx. select_all_or_error ( ) . is_empty ( )
202
199
}
203
200
204
- fn is_structural_in_adt < ' tcx > ( cx : & ConstCx < ' _ , ' tcx > , adt : AdtDef < ' tcx > ) -> bool {
201
+ fn is_structural_in_adt_value < ' tcx > ( cx : & ConstCx < ' _ , ' tcx > , adt : AdtDef < ' tcx > ) -> bool {
205
202
// As soon as an ADT has a destructor, then the drop becomes non-structural
206
203
// in its value since:
207
- // 1. The destructor may have `~const` bounds that need to be satisfied on
208
- // top of checking that the components of a specific operand are const-drop .
209
- // While this could be instead satisfied by checking that the `~const Drop`
204
+ // 1. The destructor may have `~const` bounds which are not present on the type.
205
+ // Someone needs to check that those are satisfied .
206
+ // While this could be done instead satisfied by checking that the `~const Drop`
210
207
// impl holds (i.e. replicating part of the `in_any_value_of_ty` logic above),
211
208
// even in this case, we have another problem, which is,
212
209
// 2. The destructor may *modify* the operand being dropped, so even if we
@@ -271,7 +268,7 @@ where
271
268
// then we cannot recurse on its fields. Instead,
272
269
// we fall back to checking the qualif for *any* value
273
270
// of the ADT.
274
- if def. is_union ( ) || !Q :: is_structural_in_adt ( cx, def) {
271
+ if def. is_union ( ) || !Q :: is_structural_in_adt_value ( cx, def) {
275
272
return Q :: in_any_value_of_ty ( cx, rvalue. ty ( cx. body , cx. tcx ) ) ;
276
273
}
277
274
}
0 commit comments