@@ -49,91 +49,33 @@ pub(crate) struct Qualifs<'mir, 'tcx> {
4949}
5050
5151impl < ' mir , ' tcx > Qualifs < ' mir , ' tcx > {
52- /// Returns `true` if `local` is `NeedsDrop` at the given `Location`.
53- ///
54- /// Only updates the cursor if absolutely necessary
55- pub ( crate ) fn needs_drop (
56- & mut self ,
57- ccx : & ' mir ConstCx < ' mir , ' tcx > ,
58- local : Local ,
59- location : Location ,
60- ) -> bool {
61- let ty = ccx. body . local_decls [ local] . ty ;
62- // Peeking into opaque types causes cycles if the current function declares said opaque
63- // type. Thus we avoid short circuiting on the type and instead run the more expensive
64- // analysis that looks at the actual usage within this function
65- if !ty. has_opaque_types ( ) && !NeedsDrop :: in_any_value_of_ty ( ccx, ty) {
66- return false ;
67- }
68-
69- let needs_drop = self . needs_drop . get_or_insert_with ( || {
70- let ConstCx { tcx, body, .. } = * ccx;
71-
72- FlowSensitiveAnalysis :: new ( NeedsDrop , ccx)
73- . iterate_to_fixpoint ( tcx, body, None )
74- . into_results_cursor ( body)
75- } ) ;
76-
77- needs_drop. seek_before_primary_effect ( location) ;
78- needs_drop. get ( ) . contains ( local)
79- }
80-
81- /// Returns `true` if `local` is `NeedsNonConstDrop` at the given `Location`.
82- ///
83- /// Only updates the cursor if absolutely necessary
84- pub ( crate ) fn needs_non_const_drop (
85- & mut self ,
86- ccx : & ' mir ConstCx < ' mir , ' tcx > ,
87- local : Local ,
88- location : Location ,
89- ) -> bool {
90- let ty = ccx. body . local_decls [ local] . ty ;
91- // Peeking into opaque types causes cycles if the current function declares said opaque
92- // type. Thus we avoid short circuiting on the type and instead run the more expensive
93- // analysis that looks at the actual usage within this function
94- if !ty. has_opaque_types ( ) && !NeedsNonConstDrop :: in_any_value_of_ty ( ccx, ty) {
95- return false ;
96- }
97-
98- let needs_non_const_drop = self . needs_non_const_drop . get_or_insert_with ( || {
99- let ConstCx { tcx, body, .. } = * ccx;
100-
101- FlowSensitiveAnalysis :: new ( NeedsNonConstDrop , ccx)
102- . iterate_to_fixpoint ( tcx, body, None )
103- . into_results_cursor ( body)
104- } ) ;
105-
106- needs_non_const_drop. seek_before_primary_effect ( location) ;
107- needs_non_const_drop. get ( ) . contains ( local)
108- }
109-
110- /// Returns `true` if `local` is `HasMutInterior` at the given `Location`.
52+ /// Does `Q` hold for the `local` at the given `Location`?
11153 ///
11254 /// Only updates the cursor if absolutely necessary.
113- fn has_mut_interior (
114- & mut self ,
55+ fn in_local < Q : Qualif > (
56+ qualif_results : & mut Option < QualifResults < ' mir , ' tcx , Q > > ,
11557 ccx : & ' mir ConstCx < ' mir , ' tcx > ,
11658 local : Local ,
11759 location : Location ,
11860 ) -> bool {
11961 let ty = ccx. body . local_decls [ local] . ty ;
12062 // Peeking into opaque types causes cycles if the current function declares said opaque
12163 // type. Thus we avoid short circuiting on the type and instead run the more expensive
122- // analysis that looks at the actual usage within this function
123- if !ty. has_opaque_types ( ) && !HasMutInterior :: in_any_value_of_ty ( ccx, ty) {
64+ // analysis that looks at the actual usage within this function.
65+ if !ty. has_opaque_types ( ) && !Q :: in_any_value_of_ty ( ccx, ty) {
12466 return false ;
12567 }
12668
127- let has_mut_interior = self . has_mut_interior . get_or_insert_with ( || {
69+ let qualif_results = qualif_results . get_or_insert_with ( || {
12870 let ConstCx { tcx, body, .. } = * ccx;
12971
130- FlowSensitiveAnalysis :: new ( HasMutInterior , ccx)
72+ FlowSensitiveAnalysis :: new ( ccx)
13173 . iterate_to_fixpoint ( tcx, body, None )
13274 . into_results_cursor ( body)
13375 } ) ;
13476
135- has_mut_interior . seek_before_primary_effect ( location) ;
136- has_mut_interior . get ( ) . contains ( local)
77+ qualif_results . seek_before_primary_effect ( location) ;
78+ qualif_results . get ( ) . contains ( local)
13779 }
13880
13981 fn in_return_place (
@@ -161,9 +103,19 @@ impl<'mir, 'tcx> Qualifs<'mir, 'tcx> {
161103 let return_loc = ccx. body . terminator_loc ( return_block) ;
162104
163105 ConstQualifs {
164- needs_drop : self . needs_drop ( ccx, RETURN_PLACE , return_loc) ,
165- needs_non_const_drop : self . needs_non_const_drop ( ccx, RETURN_PLACE , return_loc) ,
166- has_mut_interior : self . has_mut_interior ( ccx, RETURN_PLACE , return_loc) ,
106+ needs_drop : Self :: in_local ( & mut self . needs_drop , ccx, RETURN_PLACE , return_loc) ,
107+ needs_non_const_drop : Self :: in_local (
108+ & mut self . needs_non_const_drop ,
109+ ccx,
110+ RETURN_PLACE ,
111+ return_loc,
112+ ) ,
113+ has_mut_interior : Self :: in_local (
114+ & mut self . has_mut_interior ,
115+ ccx,
116+ RETURN_PLACE ,
117+ return_loc,
118+ ) ,
167119 tainted_by_errors,
168120 }
169121 }
@@ -435,7 +387,7 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
435387 let ty_of_dropped_place = dropped_place. ty ( self . body , self . tcx ) . ty ;
436388
437389 let needs_drop = if let Some ( local) = dropped_place. as_local ( ) {
438- self . qualifs . needs_drop ( self . ccx , local, location)
390+ Qualifs :: in_local ( & mut self . qualifs . needs_drop , self . ccx , local, location)
439391 } else {
440392 qualifs:: NeedsDrop :: in_any_value_of_ty ( self . ccx , ty_of_dropped_place)
441393 } ;
@@ -448,7 +400,7 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
448400 let needs_non_const_drop = if let Some ( local) = dropped_place. as_local ( ) {
449401 // Use the span where the local was declared as the span of the drop error.
450402 err_span = self . body . local_decls [ local] . source_info . span ;
451- self . qualifs . needs_non_const_drop ( self . ccx , local, location)
403+ Qualifs :: in_local ( & mut self . qualifs . needs_non_const_drop , self . ccx , local, location)
452404 } else {
453405 qualifs:: NeedsNonConstDrop :: in_any_value_of_ty ( self . ccx , ty_of_dropped_place)
454406 } ;
@@ -602,7 +554,14 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
602554 | Rvalue :: RawPtr ( RawPtrKind :: Const , place) => {
603555 let borrowed_place_has_mut_interior = qualifs:: in_place :: < HasMutInterior , _ > (
604556 self . ccx ,
605- & mut |local| self . qualifs . has_mut_interior ( self . ccx , local, location) ,
557+ & mut |local| {
558+ Qualifs :: in_local (
559+ & mut self . qualifs . has_mut_interior ,
560+ self . ccx ,
561+ local,
562+ location,
563+ )
564+ } ,
606565 place. as_ref ( ) ,
607566 ) ;
608567
0 commit comments