@@ -2,7 +2,7 @@ use crate::{build, shim};
22use rustc_index:: vec:: IndexVec ;
33use rustc:: hir:: def_id:: { CrateNum , DefId , LOCAL_CRATE } ;
44use rustc:: mir:: { Body , MirPhase , Promoted } ;
5- use rustc:: ty:: { TyCtxt , InstanceDef } ;
5+ use rustc:: ty:: { TyCtxt , InstanceDef , TypeFoldable } ;
66use rustc:: ty:: query:: Providers ;
77use rustc:: ty:: steal:: Steal ;
88use rustc:: hir;
@@ -39,12 +39,12 @@ pub mod uniform_array_move_out;
3939pub mod uninhabited_enum_branching;
4040
4141pub ( crate ) fn provide ( providers : & mut Providers < ' _ > ) {
42- self :: qualify_consts:: provide ( providers) ;
4342 self :: check_unsafety:: provide ( providers) ;
4443 * providers = Providers {
4544 mir_keys,
4645 mir_built,
4746 mir_const,
47+ mir_const_qualif,
4848 mir_validated,
4949 optimized_mir,
5050 is_mir_available,
@@ -185,6 +185,41 @@ pub fn run_passes(
185185 body. phase = mir_phase;
186186}
187187
188+ fn mir_const_qualif ( tcx : TyCtxt < ' _ > , def_id : DefId ) -> u8 {
189+ let const_kind = check_consts:: ConstKind :: for_item ( tcx, def_id) ;
190+
191+ // No need to const-check a non-const `fn`.
192+ if const_kind. is_none ( ) {
193+ return 0 ;
194+ }
195+
196+ // N.B., this `borrow()` is guaranteed to be valid (i.e., the value
197+ // cannot yet be stolen), because `mir_validated()`, which steals
198+ // from `mir_const(), forces this query to execute before
199+ // performing the steal.
200+ let body = & tcx. mir_const ( def_id) . borrow ( ) ;
201+
202+ if body. return_ty ( ) . references_error ( ) {
203+ tcx. sess . delay_span_bug ( body. span , "mir_const_qualif: MIR had errors" ) ;
204+ return 0 ;
205+ }
206+
207+ let item = check_consts:: Item {
208+ body,
209+ tcx,
210+ def_id,
211+ const_kind,
212+ param_env : tcx. param_env ( def_id) ,
213+ } ;
214+
215+ let mut validator = check_consts:: validation:: Validator :: new ( & item) ;
216+ validator. check_body ( ) ;
217+
218+ // We return the qualifs in the return place for every MIR body, even though it is only used
219+ // when deciding to promote a reference to a `const` for now.
220+ validator. qualifs_in_return_place ( ) . into ( )
221+ }
222+
188223fn mir_const ( tcx : TyCtxt < ' _ > , def_id : DefId ) -> & Steal < Body < ' _ > > {
189224 // Unsafety check uses the raw mir, so make sure it is run
190225 let _ = tcx. unsafety_check_result ( def_id) ;
0 commit comments