diff --git a/src/stacked_borrows.rs b/src/stacked_borrows.rs index ad7569008e20..d28c6425cd42 100644 --- a/src/stacked_borrows.rs +++ b/src/stacked_borrows.rs @@ -485,8 +485,7 @@ fn access( } } else { self.borrows.clear(); - // TODO - // self.borrows.push(ItemOrUnknown::Unknown(global.next_ptr_id)); + self.unknown_bottom = Some(global.next_ptr_id); } // Done. @@ -541,6 +540,20 @@ fn grant( let access = if new.perm.grants(AccessKind::Write) { AccessKind::Write } else { AccessKind::Read }; + // Now we figure out which item grants our parent (`derived_from`) this kind of access. + // We use that to determine where to put the new item. + let granting_idx = + self.find_granting(access, derived_from, exposed_tags).map_err(|_| { + alloc_history.grant_error( + derived_from, + new, + alloc_id, + alloc_range, + offset, + self, + ) + })?; + // Compute where to put the new item. // Either way, we ensure that we insert the new item in a way such that between // `derived_from` and the new one, there are only items *compatible with* `derived_from`. @@ -550,25 +563,17 @@ fn grant( "this case only makes sense for stack-like accesses" ); - // Now we figure out which item grants our parent (`derived_from`) this kind of access. - // We use that to determine where to put the new item. - let granting_idx = - self.find_granting(access, derived_from, exposed_tags).map_err(|_| { - alloc_history.grant_error( - derived_from, - new, - alloc_id, - alloc_range, - offset, - self, - ) - })?; - - // SharedReadWrite can coexist with "existing loans", meaning they don't act like a write - // access. Instead of popping the stack, we insert the item at the place the stack would - // be popped to (i.e., we insert it above all the write-compatible items). - // This ensures F2b by adding the new item below any potentially existing `SharedReadOnly`. - self.find_first_write_incompatible(granting_idx) + if derived_from.is_some() { + // SharedReadWrite can coexist with "existing loans", meaning they don't act like a write + // access. Instead of popping the stack, we insert the item at the place the stack would + // be popped to (i.e., we insert it above all the write-compatible items). + // This ensures F2b by adding the new item below any potentially existing `SharedReadOnly`. + self.find_first_write_incompatible(granting_idx) + } else { + // TODO: is this correct + self.borrows.clear(); + 0 + } } else { // A "safe" reborrow for a pointer that actually expects some aliasing guarantees. // Here, creating a reference actually counts as an access. @@ -590,7 +595,7 @@ fn grant( self.borrows.len() }; // Put the new item there. As an optimization, deduplicate if it is equal to one of its new neighbors. - if self.borrows[new_idx - 1] == new || self.borrows.get(new_idx) == Some(&new) { + if self.borrows.get(new_idx) == Some(&new) || new_idx > 0 && self.borrows.get(new_idx - 1) == Some(&new) { // Optimization applies, done. trace!("reborrow: avoiding adding redundant item {:?}", new); } else { diff --git a/src/stacked_borrows/diagnostics.rs b/src/stacked_borrows/diagnostics.rs index 224954c76159..6a22d9a74392 100644 --- a/src/stacked_borrows/diagnostics.rs +++ b/src/stacked_borrows/diagnostics.rs @@ -4,6 +4,8 @@ use rustc_span::{Span, SpanData}; use rustc_target::abi::Size; +use core::fmt::Debug; + use crate::helpers::{CurrentSpan, HexRange}; use crate::stacked_borrows::{err_sb_ub, AccessKind, Permission}; use crate::Item; @@ -204,9 +206,16 @@ pub fn grant_error<'tcx>( error_offset: Size, stack: &Stack, ) -> InterpError<'tcx> { + // TODO: Fix this properly + let z = &derived_from; + let f = if let Some(ref t) = z { + t as &dyn Debug + } else { + &"" as &dyn Debug + }; let action = format!( "trying to reborrow {:?} for {:?} permission at {}[{:#x}]", - derived_from, + f, new.perm, alloc_id, error_offset.bytes(), @@ -230,10 +239,16 @@ pub fn access_error<'tcx>( error_offset: Size, stack: &Stack, ) -> InterpError<'tcx> { + let z = &tag; + let f = if let Some(ref t) = z { + t as &dyn Debug + } else { + &"" as &dyn Debug + }; let action = format!( "attempting a {} using {:?} at {}[{:#x}]", access, - tag, + f, alloc_id, error_offset.bytes(), );