@@ -62,12 +62,12 @@ pub trait Qualif {
6262 /// It also determines the `Qualif`s for primitive types.
6363 fn in_any_value_of_ty < ' tcx > ( cx : & ConstCx < ' _ , ' tcx > , ty : Ty < ' tcx > ) -> bool ;
6464
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` .
6767 ///
6868 /// If this returns false, `in_any_value_of_ty` will be invoked to determine the
6969 /// 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 ;
7171}
7272
7373/// Constant containing interior mutability (`UnsafeCell<T>`).
@@ -123,7 +123,7 @@ impl Qualif for HasMutInterior {
123123 !errors. is_empty ( )
124124 }
125125
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 {
127127 // Exactly one type, `UnsafeCell`, has the `HasMutInterior` qualif inherently.
128128 // It arises structurally for all other types.
129129 !adt. is_unsafe_cell ( )
@@ -140,6 +140,7 @@ pub struct NeedsDrop;
140140impl Qualif for NeedsDrop {
141141 const ANALYSIS_NAME : & ' static str = "flow_needs_drop" ;
142142 const IS_CLEARED_ON_MOVE : bool = true ;
143+ const ALLOW_PROMOTED : bool = true ;
143144
144145 fn in_qualifs ( qualifs : & ConstQualifs ) -> bool {
145146 qualifs. needs_drop
@@ -149,7 +150,7 @@ impl Qualif for NeedsDrop {
149150 ty. needs_drop ( cx. tcx , cx. typing_env )
150151 }
151152
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 {
153154 !adt. has_dtor ( cx. tcx )
154155 }
155156}
@@ -179,34 +180,30 @@ impl Qualif for NeedsNonConstDrop {
179180 // that the components of this type are also `~const Destruct`. This
180181 // amounts to verifying that there are no values in this ADT that may have
181182 // 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 ( )
202199 }
203200
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 {
205202 // As soon as an ADT has a destructor, then the drop becomes non-structural
206203 // 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`
210207 // impl holds (i.e. replicating part of the `in_any_value_of_ty` logic above),
211208 // even in this case, we have another problem, which is,
212209 // 2. The destructor may *modify* the operand being dropped, so even if we
@@ -271,7 +268,7 @@ where
271268 // then we cannot recurse on its fields. Instead,
272269 // we fall back to checking the qualif for *any* value
273270 // 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) {
275272 return Q :: in_any_value_of_ty ( cx, rvalue. ty ( cx. body , cx. tcx ) ) ;
276273 }
277274 }
0 commit comments