@@ -25,6 +25,7 @@ use syntax::feature_gate::{emit_feature_err, GateIssue};
2525use syntax_pos:: { Span , DUMMY_SP } ;
2626
2727use std:: fmt;
28+ use std:: ops:: Deref ;
2829use std:: usize;
2930
3031use crate :: transform:: { MirPass , MirSource } ;
@@ -106,16 +107,16 @@ impl fmt::Display for Mode {
106107 }
107108}
108109
109- struct Qualifier < ' a , ' tcx > {
110+ struct ConstCx < ' a , ' tcx > {
110111 tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
111112 param_env : ty:: ParamEnv < ' tcx > ,
112113 mode : Mode ,
113114 mir : & ' a Mir < ' tcx > ,
114115
115- local_qualif : & ' a IndexVec < Local , Qualif > ,
116+ local_qualif : IndexVec < Local , Qualif > ,
116117}
117118
118- impl < ' a , ' tcx > Qualifier < ' a , ' tcx > {
119+ impl < ' a , ' tcx > ConstCx < ' a , ' tcx > {
119120 fn qualify_any_value_of_ty ( & self , ty : Ty < ' tcx > ) -> Qualif {
120121 Qualif :: any_value_of_ty ( ty, self . tcx , self . param_env )
121122 }
@@ -436,15 +437,12 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx> {
436437}
437438
438439struct Checker < ' a , ' tcx > {
439- tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
440- param_env : ty:: ParamEnv < ' tcx > ,
441- mode : Mode ,
440+ cx : ConstCx < ' a , ' tcx > ,
441+
442442 span : Span ,
443443 def_id : DefId ,
444- mir : & ' a Mir < ' tcx > ,
445444 rpo : ReversePostorder < ' a , ' tcx > ,
446445
447- local_qualif : IndexVec < Local , Qualif > ,
448446 temp_promotion_state : IndexVec < Local , TempState > ,
449447 promotion_candidates : Vec < Candidate > ,
450448}
@@ -458,6 +456,14 @@ macro_rules! unleash_miri {
458456 } }
459457}
460458
459+ impl Deref for Checker < ' a , ' tcx > {
460+ type Target = ConstCx < ' a , ' tcx > ;
461+
462+ fn deref ( & self ) -> & Self :: Target {
463+ & self . cx
464+ }
465+ }
466+
461467impl < ' a , ' tcx > Checker < ' a , ' tcx > {
462468 fn new ( tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
463469 def_id : DefId ,
@@ -489,29 +495,21 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
489495 } ) . collect ( ) ;
490496
491497 Checker {
492- mode,
498+ cx : ConstCx {
499+ tcx,
500+ param_env,
501+ mode,
502+ mir,
503+ local_qualif,
504+ } ,
493505 span : mir. span ,
494506 def_id,
495- mir,
496507 rpo,
497- tcx,
498- param_env,
499- local_qualif,
500508 temp_promotion_state : temps,
501509 promotion_candidates : vec ! [ ]
502510 }
503511 }
504512
505- fn qualifier ( & ' a self ) -> Qualifier < ' a , ' tcx > {
506- Qualifier {
507- tcx : self . tcx ,
508- param_env : self . param_env ,
509- mode : self . mode ,
510- mir : self . mir ,
511- local_qualif : & self . local_qualif ,
512- }
513- }
514-
515513 // FIXME(eddyb) we could split the errors into meaningful
516514 // categories, but enabling full miri would make that
517515 // slightly pointless (even with feature-gating).
@@ -545,7 +543,7 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
545543 if self . mir . local_kind ( index) == LocalKind :: Temp
546544 && self . temp_promotion_state [ index] . is_promotable ( ) {
547545 debug ! ( "store to promotable temp {:?} ({:?})" , index, qualif) ;
548- let slot = & mut self . local_qualif [ index] ;
546+ let slot = & mut self . cx . local_qualif [ index] ;
549547 if !slot. is_empty ( ) {
550548 span_bug ! ( self . span, "multiple assignments to {:?}" , dest) ;
551549 }
@@ -586,20 +584,23 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
586584 }
587585 }
588586 } ;
589- debug ! ( "store to var {:?}" , index) ;
587+
588+ let kind = self . mir . local_kind ( index) ;
589+ debug ! ( "store to {:?} {:?}" , kind, index) ;
590+
590591 // this is overly restrictive, because even full assignments do not clear the qualif
591592 // While we could special case full assignments, this would be inconsistent with
592593 // aggregates where we overwrite all fields via assignments, which would not get
593594 // that feature.
594- let slot = & mut self . local_qualif [ index] ;
595+ let slot = & mut self . cx . local_qualif [ index] ;
595596 * slot = * slot | qualif;
596597
597598 // Ensure we keep the `NOT_PROMOTABLE` flag is preserved.
598599 // NOTE(eddyb) this is actually unnecessary right now, as
599600 // we never replace the local's qualif (but we might in
600601 // the future) - also, if `NOT_PROMOTABLE` only matters
601602 // for `Mode::Fn`, then this is also pointless.
602- if self . mir . local_kind ( index ) == LocalKind :: Temp {
603+ if kind == LocalKind :: Temp {
603604 if !self . temp_promotion_state [ index] . is_promotable ( ) {
604605 * slot = * slot | Qualif :: NOT_PROMOTABLE ;
605606 }
@@ -664,7 +665,7 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
664665 // Account for errors in consts by using the
665666 // conservative type qualification instead.
666667 if qualif. intersects ( Qualif :: NOT_CONST ) {
667- qualif = self . qualifier ( ) . qualify_any_value_of_ty ( mir. return_ty ( ) ) ;
668+ qualif = self . qualify_any_value_of_ty ( mir. return_ty ( ) ) ;
668669 }
669670
670671
@@ -690,7 +691,7 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
690691 }
691692}
692693
693- /// Checks MIR for const-correctness, using `Qualifier `
694+ /// Checks MIR for const-correctness, using `ConstCx `
694695/// for value qualifications, and accumulates writes of
695696/// rvalue/call results to locals, in `local_qualif`.
696697/// For functions (constant or not), it also records
@@ -821,7 +822,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
821822 Operand :: Move ( ref place) => {
822823 // Mark the consumed locals to indicate later drops are noops.
823824 if let Place :: Local ( local) = * place {
824- let slot = & mut self . local_qualif [ local] ;
825+ let slot = & mut self . cx . local_qualif [ local] ;
825826 * slot = * slot - Qualif :: NEEDS_DROP ;
826827 }
827828 }
@@ -960,7 +961,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
960961 if let TerminatorKind :: Call { ref func, ref args, ref destination, .. } = * kind {
961962 if let Some ( ( ref dest, _) ) = * destination {
962963 let ty = dest. ty ( self . mir , self . tcx ) . to_ty ( self . tcx ) ;
963- let qualif = self . qualifier ( ) . qualify_call ( func, args, ty) ;
964+ let qualif = self . qualify_call ( func, args, ty) ;
964965 self . assign ( dest, qualif, location) ;
965966 }
966967
@@ -1013,7 +1014,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
10131014 // stable const fns or unstable const fns
10141015 // with their feature gate active
10151016 // FIXME(eddyb) move stability checks from `is_const_fn` here.
1016- } else if self . qualifier ( ) . is_const_panic_fn ( def_id) {
1017+ } else if self . is_const_panic_fn ( def_id) {
10171018 // Check the const_panic feature gate.
10181019 // FIXME: cannot allow this inside `allow_internal_unstable`
10191020 // because that would make `panic!` insta stable in constants,
@@ -1093,7 +1094,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
10931094 // which happens even without the user requesting it.
10941095 // We can error out with a hard error if the argument is not
10951096 // constant here.
1096- let arg_qualif = self . qualifier ( ) . qualify_operand ( arg) ;
1097+ let arg_qualif = self . qualify_operand ( arg) ;
10971098 if ( arg_qualif - Qualif :: NOT_PROMOTABLE ) . is_empty ( ) {
10981099 debug ! ( "visit_terminator_kind: candidate={:?}" , candidate) ;
10991100 self . promotion_candidates . push ( candidate) ;
@@ -1157,7 +1158,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
11571158 rvalue : & Rvalue < ' tcx > ,
11581159 location : Location ) {
11591160 debug ! ( "visit_assign: dest={:?} rvalue={:?} location={:?}" , dest, rvalue, location) ;
1160- let mut qualif = self . qualifier ( ) . qualify_rvalue ( rvalue) ;
1161+ let mut qualif = self . qualify_rvalue ( rvalue) ;
11611162
11621163 if let Rvalue :: Ref ( _, kind, ref place) = * rvalue {
11631164 // Getting `MUTABLE_INTERIOR` from `qualify_rvalue` means
0 commit comments