@@ -828,7 +828,9 @@ impl<'tcx> Tree {
828828 ) -> InterpResult < ' tcx > {
829829 self . perform_access (
830830 prov,
831- Some ( ( access_range, AccessKind :: Write , diagnostics:: AccessCause :: Dealloc ) ) ,
831+ access_range,
832+ AccessKind :: Write ,
833+ diagnostics:: AccessCause :: Dealloc ,
832834 global,
833835 alloc_id,
834836 span,
@@ -903,14 +905,6 @@ impl<'tcx> Tree {
903905 /// to each location of the first component of `access_range_and_kind`,
904906 /// on every tag of the allocation.
905907 ///
906- /// If `access_range_and_kind` is `None`, this is interpreted as the special
907- /// access that is applied on protector release:
908- /// - the access will be applied only to accessed locations of the allocation,
909- /// - it will not be visible to children,
910- /// - it will be recorded as a `FnExit` diagnostic access
911- /// - and it will be a read except if the location is `Unique`, i.e. has been written to,
912- /// in which case it will be a write.
913- ///
914908 /// `LocationState::perform_access` will take care of raising transition
915909 /// errors and updating the `accessed` status of each location,
916910 /// this traversal adds to that:
@@ -920,7 +914,9 @@ impl<'tcx> Tree {
920914 pub fn perform_access (
921915 & mut self ,
922916 prov : ProvenanceExtra ,
923- access_range_and_kind : Option < ( AllocRange , AccessKind , diagnostics:: AccessCause ) > ,
917+ access_range : AllocRange ,
918+ access_kind : AccessKind ,
919+ access_cause : AccessCause , // diagnostics
924920 global : & GlobalState ,
925921 alloc_id : AllocId , // diagnostics
926922 span : Span , // diagnostics
@@ -934,61 +930,75 @@ impl<'tcx> Tree {
934930 ProvenanceExtra :: Concrete ( tag) => Some ( self . tag_mapping . get ( & tag) . unwrap ( ) ) ,
935931 ProvenanceExtra :: Wildcard => None ,
936932 } ;
937- if let Some ( ( access_range, access_kind, access_cause) ) = access_range_and_kind {
938- // Default branch: this is a "normal" access through a known range.
939- // We iterate over affected locations and traverse the tree for each of them.
940- for ( loc_range, loc) in self . locations . iter_mut ( access_range. start , access_range. size ) {
933+ // We iterate over affected locations and traverse the tree for each of them.
934+ for ( loc_range, loc) in self . locations . iter_mut ( access_range. start , access_range. size ) {
935+ loc. perform_access (
936+ self . roots . iter ( ) . copied ( ) ,
937+ & mut self . nodes ,
938+ source_idx,
939+ loc_range,
940+ Some ( access_range) ,
941+ access_kind,
942+ access_cause,
943+ global,
944+ alloc_id,
945+ span,
946+ ChildrenVisitMode :: VisitChildrenOfAccessed ,
947+ ) ?;
948+ }
949+ interp_ok ( ( ) )
950+ }
951+ /// This is the special access that is applied on protector release:
952+ /// - the access will be applied only to accessed locations of the allocation,
953+ /// - it will not be visible to children,
954+ /// - it will be recorded as a `FnExit` diagnostic access
955+ /// - and it will be a read except if the location is `Unique`, i.e. has been written to,
956+ /// in which case it will be a write.
957+ /// - otherwise identical to `Tree::perform_access`
958+ pub fn perform_protector_end_access (
959+ & mut self ,
960+ tag : BorTag ,
961+ global : & GlobalState ,
962+ alloc_id : AllocId , // diagnostics
963+ span : Span , // diagnostics
964+ ) -> InterpResult < ' tcx > {
965+ #[ cfg( feature = "expensive-consistency-checks" ) ]
966+ if self . roots . len ( ) > 1 {
967+ self . verify_wildcard_consistency ( global) ;
968+ }
969+
970+ let source_idx = self . tag_mapping . get ( & tag) . unwrap ( ) ;
971+
972+ // This is a special access through the entire allocation.
973+ // It actually only affects `accessed` locations, so we need
974+ // to filter on those before initiating the traversal.
975+ //
976+ // In addition this implicit access should not be visible to children,
977+ // thus the use of `traverse_nonchildren`.
978+ // See the test case `returned_mut_is_usable` from
979+ // `tests/pass/tree_borrows/tree-borrows.rs` for an example of
980+ // why this is important.
981+ for ( loc_range, loc) in self . locations . iter_mut_all ( ) {
982+ // Only visit accessed permissions
983+ if let Some ( p) = loc. perms . get ( source_idx)
984+ && let Some ( access_kind) = p. permission . protector_end_access ( )
985+ && p. accessed
986+ {
987+ let access_cause = diagnostics:: AccessCause :: FnExit ( access_kind) ;
941988 loc. perform_access (
942989 self . roots . iter ( ) . copied ( ) ,
943990 & mut self . nodes ,
944- source_idx,
991+ Some ( source_idx) ,
945992 loc_range,
946- Some ( access_range ) ,
993+ None ,
947994 access_kind,
948995 access_cause,
949996 global,
950997 alloc_id,
951998 span,
952- ChildrenVisitMode :: VisitChildrenOfAccessed ,
999+ ChildrenVisitMode :: SkipChildrenOfAccessed ,
9531000 ) ?;
9541001 }
955- } else {
956- // This is a special access through the entire allocation.
957- // It actually only affects `accessed` locations, so we need
958- // to filter on those before initiating the traversal.
959- //
960- // In addition this implicit access should not be visible to children,
961- // thus the use of `traverse_nonchildren`.
962- // See the test case `returned_mut_is_usable` from
963- // `tests/pass/tree_borrows/tree-borrows.rs` for an example of
964- // why this is important.
965-
966- // Wildcard references are never protected. So this can never be
967- // called with a wildcard reference.
968- let source_idx = source_idx. unwrap ( ) ;
969-
970- for ( loc_range, loc) in self . locations . iter_mut_all ( ) {
971- // Only visit accessed permissions
972- if let Some ( p) = loc. perms . get ( source_idx)
973- && let Some ( access_kind) = p. permission . protector_end_access ( )
974- && p. accessed
975- {
976- let access_cause = diagnostics:: AccessCause :: FnExit ( access_kind) ;
977- loc. perform_access (
978- self . roots . iter ( ) . copied ( ) ,
979- & mut self . nodes ,
980- Some ( source_idx) ,
981- loc_range,
982- None ,
983- access_kind,
984- access_cause,
985- global,
986- alloc_id,
987- span,
988- ChildrenVisitMode :: SkipChildrenOfAccessed ,
989- ) ?;
990- }
991- }
9921002 }
9931003 interp_ok ( ( ) )
9941004 }
0 commit comments