@@ -1007,16 +1007,16 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> {
10071007 operand : & mut Operand < ' tcx > ,
10081008 location : Location ,
10091009 ) -> Option < VnIndex > {
1010- match * operand {
1011- Operand :: Constant ( ref constant) => Some ( self . insert_constant ( constant. const_ ) ) ,
1010+ let value = match * operand {
1011+ Operand :: Constant ( ref constant) => self . insert_constant ( constant. const_ ) ,
10121012 Operand :: Copy ( ref mut place) | Operand :: Move ( ref mut place) => {
1013- let value = self . simplify_place_value ( place, location) ?;
1014- if let Some ( const_) = self . try_as_constant ( value) {
1015- * operand = Operand :: Constant ( Box :: new ( const_) ) ;
1016- }
1017- Some ( value)
1013+ self . simplify_place_value ( place, location) ?
10181014 }
1015+ } ;
1016+ if let Some ( const_) = self . try_as_constant ( value) {
1017+ * operand = Operand :: Constant ( Box :: new ( const_) ) ;
10191018 }
1019+ Some ( value)
10201020 }
10211021
10221022 #[ instrument( level = "trace" , skip( self ) , ret) ]
@@ -1791,14 +1791,28 @@ impl<'tcx> VnState<'_, '_, 'tcx> {
17911791
17921792 /// If `index` is a `Value::Constant`, return the `Constant` to be put in the MIR.
17931793 fn try_as_constant ( & mut self , index : VnIndex ) -> Option < ConstOperand < ' tcx > > {
1794- // This was already constant in MIR, do not change it. If the constant is not
1795- // deterministic, adding an additional mention of it in MIR will not give the same value as
1796- // the former mention.
1797- if let Value :: Constant { value, disambiguator : None } = self . get ( index) {
1798- debug_assert ! ( value. is_deterministic( ) ) ;
1794+ let value = self . get ( index) ;
1795+
1796+ // This was already an *evaluated* constant in MIR, do not change it.
1797+ if let Value :: Constant { value, disambiguator : None } = value
1798+ && let Const :: Val ( ..) = value
1799+ {
17991800 return Some ( ConstOperand { span : DUMMY_SP , user_ty : None , const_ : value } ) ;
18001801 }
18011802
1803+ if let Some ( value) = self . try_as_evaluated_constant ( index) {
1804+ return Some ( ConstOperand { span : DUMMY_SP , user_ty : None , const_ : value } ) ;
1805+ }
1806+
1807+ // We failed to provide an evaluated form, fallback to using the unevaluated constant.
1808+ if let Value :: Constant { value, disambiguator : None } = value {
1809+ return Some ( ConstOperand { span : DUMMY_SP , user_ty : None , const_ : value } ) ;
1810+ }
1811+
1812+ None
1813+ }
1814+
1815+ fn try_as_evaluated_constant ( & mut self , index : VnIndex ) -> Option < Const < ' tcx > > {
18021816 let op = self . eval_to_const ( index) ?;
18031817 if op. layout . is_unsized ( ) {
18041818 // Do not attempt to propagate unsized locals.
@@ -1812,8 +1826,7 @@ impl<'tcx> VnState<'_, '_, 'tcx> {
18121826 // FIXME: remove this hack once https://github.com/rust-lang/rust/issues/79738 is fixed.
18131827 assert ! ( !value. may_have_provenance( self . tcx, op. layout. size) ) ;
18141828
1815- let const_ = Const :: Val ( value, op. layout . ty ) ;
1816- Some ( ConstOperand { span : DUMMY_SP , user_ty : None , const_ } )
1829+ Some ( Const :: Val ( value, op. layout . ty ) )
18171830 }
18181831
18191832 /// Construct a place which holds the same value as `index` and for which all locals strictly
0 commit comments