@@ -697,16 +697,16 @@ macro_rules! define_qualifs {
697
697
( $( $Q: ident, $field: ident ) ;* $( ; ) ? ) => {
698
698
$(
699
699
impl Index <$Q> for Resolvers <' mir, ' tcx> {
700
- type Output = FlowSensitiveResolver < ' mir, ' tcx, $Q>;
700
+ type Output = dyn ' mir + QualifResolver < ' tcx, $Q>;
701
701
702
702
fn index( & self , _: $Q) -> & Self :: Output {
703
- & self . $field
703
+ & * self . $field
704
704
}
705
705
}
706
706
707
707
impl IndexMut <$Q> for Resolvers <' mir, ' tcx> {
708
708
fn index_mut( & mut self , _: $Q) -> & mut Self :: Output {
709
- & mut self . $field
709
+ & mut * self . $field
710
710
}
711
711
}
712
712
) *
@@ -840,10 +840,10 @@ trait QualifResolver<'tcx, Q>: Visitor<'tcx> {
840
840
/// `resolvers[NeedsDrop]`). This chicanery makes the use of macros like `for_each_qualif` more
841
841
/// convenient.
842
842
pub struct Resolvers < ' mir , ' tcx > {
843
- needs_drop : FlowSensitiveResolver < ' mir , ' tcx , NeedsDrop > ,
844
- has_mut_interior : FlowSensitiveResolver < ' mir , ' tcx , HasMutInterior > ,
845
- is_not_promotable : FlowSensitiveResolver < ' mir , ' tcx , IsNotPromotable > ,
846
- is_not_implicitly_promotable : FlowSensitiveResolver < ' mir , ' tcx , IsNotImplicitlyPromotable > ,
843
+ needs_drop : Box < dyn ' mir + QualifResolver < ' tcx , NeedsDrop > > ,
844
+ has_mut_interior : Box < dyn ' mir + QualifResolver < ' tcx , HasMutInterior > > ,
845
+ is_not_promotable : Box < dyn ' mir + QualifResolver < ' tcx , IsNotPromotable > > ,
846
+ is_not_implicitly_promotable : Box < dyn ' mir + QualifResolver < ' tcx , IsNotImplicitlyPromotable > > ,
847
847
}
848
848
849
849
impl Resolvers < ' mir , ' tcx > {
@@ -867,34 +867,52 @@ impl Resolvers<'mir, 'tcx> {
867
867
let borrowed_locals = dataflow:: DataflowResultsCursor :: new ( borrowed_locals, cx. body ) ;
868
868
let borrowed_locals = Rc :: new ( RefCell :: new ( borrowed_locals) ) ;
869
869
870
- let needs_drop = FlowSensitiveResolver :: new (
871
- NeedsDrop ,
872
- cx,
873
- borrowed_locals. clone ( ) ,
874
- temp_promotion_state,
875
- & dead_unwinds,
876
- ) ;
877
- let has_mut_interior = FlowSensitiveResolver :: new (
878
- HasMutInterior ,
879
- cx,
880
- borrowed_locals. clone ( ) ,
881
- temp_promotion_state,
882
- & dead_unwinds,
883
- ) ;
884
- let is_not_promotable = FlowSensitiveResolver :: new (
870
+ let needs_drop = if cx. mode == Mode :: NonConstFn {
871
+ Box :: new ( TempOnlyResolver :: new (
872
+ NeedsDrop ,
873
+ cx,
874
+ borrowed_locals. clone ( ) ,
875
+ temp_promotion_state,
876
+ ) ) as Box < _ >
877
+ } else {
878
+ Box :: new ( FlowSensitiveResolver :: new (
879
+ NeedsDrop ,
880
+ cx,
881
+ borrowed_locals. clone ( ) ,
882
+ temp_promotion_state,
883
+ & dead_unwinds,
884
+ ) ) as Box < _ >
885
+ } ;
886
+
887
+ let has_mut_interior = if cx. mode == Mode :: NonConstFn {
888
+ Box :: new ( TempOnlyResolver :: new (
889
+ HasMutInterior ,
890
+ cx,
891
+ borrowed_locals. clone ( ) ,
892
+ temp_promotion_state,
893
+ ) ) as Box < _ >
894
+ } else {
895
+ Box :: new ( FlowSensitiveResolver :: new (
896
+ HasMutInterior ,
897
+ cx,
898
+ borrowed_locals. clone ( ) ,
899
+ temp_promotion_state,
900
+ & dead_unwinds,
901
+ ) ) as Box < _ >
902
+ } ;
903
+
904
+ let is_not_promotable = Box :: new ( TempOnlyResolver :: new (
885
905
IsNotPromotable ,
886
906
cx,
887
907
borrowed_locals. clone ( ) ,
888
908
temp_promotion_state,
889
- & dead_unwinds,
890
- ) ;
891
- let is_not_implicitly_promotable = FlowSensitiveResolver :: new (
909
+ ) ) ;
910
+ let is_not_implicitly_promotable = Box :: new ( TempOnlyResolver :: new (
892
911
IsNotImplicitlyPromotable ,
893
912
cx,
894
913
borrowed_locals. clone ( ) ,
895
914
temp_promotion_state,
896
- & dead_unwinds,
897
- ) ;
915
+ ) ) ;
898
916
899
917
Resolvers {
900
918
needs_drop,
@@ -905,6 +923,72 @@ impl Resolvers<'mir, 'tcx> {
905
923
}
906
924
}
907
925
926
+ struct TempOnlyResolver < ' mir , ' tcx , Q > {
927
+ cx : ConstCx < ' mir , ' tcx > ,
928
+ borrowed_locals : BorrowedLocalsResults < ' mir , ' tcx > ,
929
+ per_local : BitSet < Local > ,
930
+ _qualif : PhantomData < Q > ,
931
+ }
932
+
933
+ impl < Q > TempOnlyResolver < ' mir , ' tcx , Q >
934
+ where
935
+ Q : Qualif ,
936
+ {
937
+ fn new (
938
+ _: Q ,
939
+ cx : & ConstCx < ' mir , ' tcx > ,
940
+ borrowed_locals : BorrowedLocalsResults < ' mir , ' tcx > ,
941
+ temp_promotion_state : & IndexVec < Local , TempState > ,
942
+ ) -> Self {
943
+ let mut per_local = BitSet :: new_empty ( cx. body . local_decls . len ( ) ) ;
944
+ initialize_qualifs :: < Q > ( & mut per_local, cx, temp_promotion_state) ;
945
+
946
+ TempOnlyResolver {
947
+ cx : ( * cx) . clone ( ) ,
948
+ borrowed_locals,
949
+ per_local,
950
+ _qualif : PhantomData ,
951
+ }
952
+ }
953
+ }
954
+
955
+
956
+ impl < Q > Visitor < ' tcx > for TempOnlyResolver < ' _ , ' tcx , Q >
957
+ where
958
+ Q : Qualif
959
+ {
960
+ fn visit_statement ( & mut self , statement : & Statement < ' tcx > , location : Location ) {
961
+ QualifPropagator :: < Q > :: new ( & self . cx , & mut self . per_local , & self . borrowed_locals )
962
+ . visit_statement ( statement, location) ;
963
+ }
964
+
965
+ fn visit_terminator ( & mut self , terminator : & Terminator < ' tcx > , location : Location ) {
966
+ QualifPropagator :: < Q > :: new ( & self . cx , & mut self . per_local , & self . borrowed_locals )
967
+ . visit_terminator ( terminator, location) ;
968
+
969
+ if let mir:: TerminatorKind :: Call {
970
+ destination : Some ( ( return_place, _) ) ,
971
+ func,
972
+ args,
973
+ ..
974
+ } = & terminator. kind {
975
+ let return_ty = return_place. ty ( self . cx . body , self . cx . tcx ) . ty ;
976
+ let in_call = Q :: in_call ( & self . cx , & mut self . per_local , func, args, return_ty) ;
977
+ QualifPropagator :: < Q > :: new ( & self . cx , & mut self . per_local , & self . borrowed_locals )
978
+ . assign_qualif ( return_place, in_call, location) ;
979
+ }
980
+ }
981
+ }
982
+
983
+ impl < Q > QualifResolver < ' tcx , Q > for TempOnlyResolver < ' _ , ' tcx , Q >
984
+ where
985
+ Q : Qualif
986
+ {
987
+ fn get ( & mut self ) -> & BitSet < Local > {
988
+ & self . per_local
989
+ }
990
+ }
991
+
908
992
struct FlowSensitiveResolver < ' mir , ' tcx , Q >
909
993
where
910
994
Q : Qualif
@@ -1116,9 +1200,8 @@ where
1116
1200
borrowed_locals. seek ( location) ;
1117
1201
1118
1202
for local in borrowed_locals. get ( ) . iter ( ) {
1119
- // FIXME: This is unsound. Mutable borrows can still mutate types that aren't `Freeze`.
1120
1203
let ty = self . cx . body . local_decls [ local] . ty ;
1121
- if !ty . is_freeze ( self . cx . tcx , self . cx . param_env , DUMMY_SP ) {
1204
+ if Q :: in_any_value_of_ty ( & self . cx , ty ) . unwrap_or ( true ) {
1122
1205
self . qualifs_per_local . insert ( local) ;
1123
1206
}
1124
1207
}
@@ -2220,7 +2303,8 @@ fn mir_const_qualif(tcx: TyCtxt<'_>, def_id: DefId) -> (u8, &BitSet<Local>) {
2220
2303
return ( 1 << IsNotPromotable :: IDX , tcx. arena . alloc ( BitSet :: new_empty ( 0 ) ) ) ;
2221
2304
}
2222
2305
2223
- Checker :: new ( tcx, def_id, body, Mode :: Const ) . check_const ( )
2306
+ let mut checker = Checker :: new ( tcx, def_id, body, Mode :: Const ) ;
2307
+ checker. check_const ( )
2224
2308
}
2225
2309
2226
2310
pub struct QualifyAndPromoteConstants < ' tcx > {
0 commit comments