Skip to content

Commit cddd85e

Browse files
committed
Move SB diagnostics to a module
1 parent 5861d13 commit cddd85e

File tree

5 files changed

+311
-251
lines changed

5 files changed

+311
-251
lines changed

src/diagnostics.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use rustc_middle::ty;
88
use rustc_span::{source_map::DUMMY_SP, Span, SpanData, Symbol};
99

1010
use crate::helpers::HexRange;
11-
use crate::stacked_borrows::{AccessKind, SbTag, TagHistory};
11+
use crate::stacked_borrows::{diagnostics::TagHistory, AccessKind, SbTag};
1212
use crate::*;
1313

1414
/// Details of premature program termination.

src/eval.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ use rustc_target::spec::abi::Abi;
1515

1616
use rustc_session::config::EntryFnType;
1717

18-
use std::collections::HashSet;
1918
use rustc_span::DUMMY_SP;
19+
use std::collections::HashSet;
2020

2121
use crate::*;
2222

src/machine.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -776,6 +776,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'mir, 'tcx> {
776776

777777
// This is potentially a performance hazard.
778778
// Factoring it into its own function lets us keep an eye on how much it shows up in a profile.
779+
///
779780
fn set_current_span<'mir, 'tcx: 'mir>(machine: &Evaluator<'mir, 'tcx>) {
780781
if let Some(sb) = machine.stacked_borrows.as_ref() {
781782
if sb.borrow().current_span != DUMMY_SP {

src/stacked_borrows.rs

Lines changed: 9 additions & 249 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,18 @@ use rustc_middle::ty::{
1414
self,
1515
layout::{HasParamEnv, LayoutOf},
1616
};
17+
use rustc_span::Span;
1718
use rustc_span::DUMMY_SP;
18-
use rustc_span::{Span, SpanData};
1919
use rustc_target::abi::Size;
2020
use std::collections::HashSet;
2121

22-
use crate::helpers::HexRange;
2322
use crate::*;
2423

24+
pub mod diagnostics;
25+
use diagnostics::{AllocHistory, GlobalStateExt, StackExt};
26+
27+
use diagnostics::TagHistory;
28+
2529
pub type PtrId = NonZeroU64;
2630
pub type CallId = NonZeroU64;
2731
pub type AllocExtra = Stacks;
@@ -120,47 +124,6 @@ pub struct GlobalStateInner {
120124
pub(crate) current_span: Span,
121125
}
122126

123-
#[derive(Debug, Default)]
124-
struct AllocHistory {
125-
// The time tags can be compressed down to one bit per event, by just storing a Vec<u8>
126-
// where each bit is set to indicate if the event was a creation or a retag
127-
current_time: usize,
128-
creations: smallvec::SmallVec<[Event; 2]>,
129-
invalidations: smallvec::SmallVec<[Event; 1]>,
130-
protectors: smallvec::SmallVec<[Protection; 1]>,
131-
}
132-
133-
#[derive(Debug)]
134-
struct Protection {
135-
orig_tag: SbTag,
136-
tag: SbTag,
137-
span: Span,
138-
}
139-
140-
#[derive(Debug)]
141-
struct Event {
142-
time: usize,
143-
parent: Option<SbTag>,
144-
tag: SbTag,
145-
range: AllocRange,
146-
span: Span,
147-
}
148-
149-
pub enum TagHistory {
150-
Tagged {
151-
tag: SbTag,
152-
created: (AllocRange, SpanData),
153-
invalidated: Option<(AllocRange, SpanData)>,
154-
protected: Option<(SbTag, SpanData, SpanData)>,
155-
},
156-
Untagged {
157-
recently_created: Option<(AllocRange, SpanData)>,
158-
recently_invalidated: Option<(AllocRange, SpanData)>,
159-
matching_created: Option<(AllocRange, SpanData)>,
160-
protected: Option<(SbTag, SpanData, SpanData)>,
161-
},
162-
}
163-
164127
/// We need interior mutable access to the global state.
165128
pub type GlobalState = RefCell<GlobalStateInner>;
166129

@@ -269,144 +232,10 @@ impl GlobalStateInner {
269232
self.base_ptr_ids.try_insert(id, tag).unwrap();
270233
tag
271234
}
272-
273-
fn add_creation(
274-
&mut self,
275-
parent: Option<SbTag>,
276-
tag: SbTag,
277-
alloc: AllocId,
278-
range: AllocRange,
279-
) {
280-
let extras = self.extras.entry(alloc).or_default();
281-
extras.creations.push(Event {
282-
parent,
283-
tag,
284-
range,
285-
span: self.current_span,
286-
time: extras.current_time,
287-
});
288-
extras.current_time += 1;
289-
}
290-
291-
fn add_invalidation(&mut self, tag: SbTag, alloc: AllocId, range: AllocRange) {
292-
let extras = self.extras.entry(alloc).or_default();
293-
extras.invalidations.push(Event {
294-
parent: None,
295-
tag,
296-
range,
297-
span: self.current_span,
298-
time: extras.current_time,
299-
});
300-
extras.current_time += 1;
301-
}
302-
303-
fn add_protector(&mut self, orig_tag: SbTag, tag: SbTag, alloc: AllocId) {
304-
let extras = self.extras.entry(alloc).or_default();
305-
extras.protectors.push(Protection { orig_tag, tag, span: self.current_span });
306-
extras.current_time += 1;
307-
}
308-
309-
fn get_stack_history(
310-
&self,
311-
tag: SbTag,
312-
alloc: AllocId,
313-
alloc_range: AllocRange,
314-
offset: Size,
315-
protector_tag: Option<SbTag>,
316-
) -> Option<TagHistory> {
317-
let extras = self.extras.get(&alloc)?;
318-
let protected = protector_tag
319-
.and_then(|protector| {
320-
extras.protectors.iter().find_map(|protection| {
321-
if protection.tag == protector {
322-
Some((protection.orig_tag, protection.span.data()))
323-
} else {
324-
None
325-
}
326-
})
327-
})
328-
.and_then(|(tag, call_span)| {
329-
extras.creations.iter().rev().find_map(|event| {
330-
if event.tag == tag {
331-
Some((event.parent?, event.span.data(), call_span))
332-
} else {
333-
None
334-
}
335-
})
336-
});
337-
if let SbTag::Tagged(_) = tag {
338-
let get_matching = |events: &[Event]| {
339-
events.iter().rev().find_map(|event| {
340-
if event.tag == tag { Some((event.range, event.span.data())) } else { None }
341-
})
342-
};
343-
Some(TagHistory::Tagged {
344-
tag,
345-
created: get_matching(&extras.creations)?,
346-
invalidated: get_matching(&extras.invalidations),
347-
protected,
348-
})
349-
} else {
350-
let mut created_time = 0;
351-
// Find the most recently created tag that satsfies this offset
352-
let recently_created = extras.creations.iter().rev().find_map(|event| {
353-
if event.tag == tag && offset >= event.range.start && offset < event.range.end() {
354-
created_time = event.time;
355-
Some((event.range, event.span.data()))
356-
} else {
357-
None
358-
}
359-
});
360-
361-
// Find a different recently created tag that satisfies this whole operation, predates
362-
// the recently created tag, and has a different span.
363-
// We're trying to make a guess at which span the user wanted to provide the tag that
364-
// they're using.
365-
let matching_created = if let Some((_created_range, created_span)) = recently_created {
366-
extras.creations.iter().rev().find_map(|event| {
367-
if event.tag == tag
368-
&& alloc_range.start >= event.range.start
369-
&& alloc_range.end() <= event.range.end()
370-
&& event.span.data() != created_span
371-
&& event.time != created_time
372-
{
373-
Some((event.range, event.span.data()))
374-
} else {
375-
None
376-
}
377-
})
378-
} else {
379-
None
380-
};
381-
382-
let recently_invalidated = if recently_created.is_some() {
383-
// Find the most recent invalidation of this tag which post-dates the creation
384-
let mut found = None;
385-
for event in extras.invalidations.iter().rev() {
386-
if event.time < created_time {
387-
break;
388-
}
389-
if event.tag == tag && offset >= event.range.start && offset < event.range.end()
390-
{
391-
found = Some((event.range, event.span.data()))
392-
}
393-
}
394-
found
395-
} else {
396-
None
397-
};
398-
Some(TagHistory::Untagged {
399-
recently_created,
400-
matching_created,
401-
recently_invalidated,
402-
protected,
403-
})
404-
}
405-
}
406235
}
407236

408237
/// Error reporting
409-
fn err_sb_ub(
238+
pub fn err_sb_ub(
410239
msg: String,
411240
help: Option<String>,
412241
history: Option<TagHistory>,
@@ -498,7 +327,7 @@ impl<'tcx> Stack {
498327
/// `None` during a deallocation.
499328
fn check_protector(
500329
item: &Item,
501-
provoking_access: Option<(SbTag, AllocId, AllocRange, Size)>, // just for debug printing amd error messages
330+
provoking_access: Option<(SbTag, AllocId, AllocRange, Size)>, // just for debug printing and error messages
502331
global: &GlobalStateInner,
503332
) -> InterpResult<'tcx> {
504333
if let SbTag::Tagged(id) = item.tag {
@@ -600,7 +429,7 @@ impl<'tcx> Stack {
600429
fn dealloc(
601430
&mut self,
602431
tag: SbTag,
603-
(alloc_id, alloc_range, offset): (AllocId, AllocRange, Size), // just for debug printing amd error messages
432+
(alloc_id, alloc_range, offset): (AllocId, AllocRange, Size), // just for debug printing and error messages
604433
global: &GlobalStateInner,
605434
) -> InterpResult<'tcx> {
606435
// Step 1: Find granting item.
@@ -681,75 +510,6 @@ impl<'tcx> Stack {
681510

682511
Ok(())
683512
}
684-
685-
/// Report a descriptive error when `new` could not be granted from `derived_from`.
686-
fn grant_error(
687-
&self,
688-
derived_from: SbTag,
689-
new: Item,
690-
alloc_id: AllocId,
691-
alloc_range: AllocRange,
692-
error_offset: Size,
693-
global: &GlobalStateInner,
694-
) -> InterpError<'static> {
695-
let action = format!(
696-
"trying to reborrow {:?} for {:?} permission at {}[{:#x}]",
697-
derived_from,
698-
new.perm,
699-
alloc_id,
700-
error_offset.bytes(),
701-
);
702-
err_sb_ub(
703-
format!("{}{}", action, self.error_cause(derived_from)),
704-
Some(Self::operation_summary("a reborrow", alloc_id, alloc_range)),
705-
global.get_stack_history(derived_from, alloc_id, alloc_range, error_offset, None),
706-
)
707-
}
708-
709-
/// Report a descriptive error when `access` is not permitted based on `tag`.
710-
fn access_error(
711-
&self,
712-
access: AccessKind,
713-
tag: SbTag,
714-
alloc_id: AllocId,
715-
alloc_range: AllocRange,
716-
error_offset: Size,
717-
global: &GlobalStateInner,
718-
) -> InterpError<'static> {
719-
let action = format!(
720-
"attempting a {} using {:?} at {}[{:#x}]",
721-
access,
722-
tag,
723-
alloc_id,
724-
error_offset.bytes(),
725-
);
726-
err_sb_ub(
727-
format!("{}{}", action, self.error_cause(tag)),
728-
Some(Self::operation_summary("an access", alloc_id, alloc_range)),
729-
global.get_stack_history(tag, alloc_id, alloc_range, error_offset, None),
730-
)
731-
}
732-
733-
fn operation_summary(
734-
operation: &'static str,
735-
alloc_id: AllocId,
736-
alloc_range: AllocRange,
737-
) -> String {
738-
format!(
739-
"this error occurs as part of {} at {:?}{}",
740-
operation,
741-
alloc_id,
742-
HexRange(alloc_range)
743-
)
744-
}
745-
746-
fn error_cause(&self, tag: SbTag) -> &'static str {
747-
if self.borrows.iter().any(|item| item.tag == tag && item.perm != Permission::Disabled) {
748-
", but that tag only grants SharedReadOnly permission for this location"
749-
} else {
750-
", but that tag does not exist in the borrow stack for this location"
751-
}
752-
}
753513
}
754514
// # Stacked Borrows Core End
755515

0 commit comments

Comments
 (0)