4
4
use std:: cell:: RefCell ;
5
5
use std:: collections:: { HashMap , HashSet } ;
6
6
use std:: fmt;
7
+ use std:: fmt:: Write ;
7
8
use std:: num:: NonZeroU64 ;
8
9
use std:: rc:: Rc ;
9
10
@@ -278,10 +279,13 @@ impl<'tcx> Stack {
278
279
if let Some ( call) = item. protector {
279
280
if global. is_active ( call) {
280
281
if let Some ( tag) = tag {
281
- throw_ub ! ( UbExperimental ( format!(
282
- "not granting access to tag {:?} because incompatible item is protected: {:?}" ,
283
- tag, item
284
- ) ) ) ;
282
+ return Err ( err_ub_experimental (
283
+ tag,
284
+ format ! (
285
+ "not granting access to tag {:?} because incompatible item is protected: {:?}" ,
286
+ tag, item
287
+ ) ,
288
+ ) ) ;
285
289
} else {
286
290
throw_ub ! ( UbExperimental ( format!(
287
291
"deallocating while item is protected: {:?}" ,
@@ -300,10 +304,10 @@ impl<'tcx> Stack {
300
304
301
305
// Step 1: Find granting item.
302
306
let granting_idx = self . find_granting ( access, tag) . ok_or_else ( || {
303
- err_ub ! ( UbExperimental ( format! (
304
- "no item granting {} to tag {:?} found in borrow stack" ,
305
- access, tag,
306
- ) ) )
307
+ err_ub_experimental (
308
+ tag,
309
+ format ! ( "no item granting {} to tag {:?} found in borrow stack." , access, tag) ,
310
+ )
307
311
} ) ?;
308
312
309
313
// Step 2: Remove incompatible items above them. Make sure we do not remove protected
@@ -344,10 +348,11 @@ impl<'tcx> Stack {
344
348
fn dealloc ( & mut self , tag : Tag , global : & GlobalState ) -> InterpResult < ' tcx > {
345
349
// Step 1: Find granting item.
346
350
self . find_granting ( AccessKind :: Write , tag) . ok_or_else ( || {
347
- err_ub ! ( UbExperimental ( format!(
351
+ err_ub_experimental (
352
+ tag, format ! (
348
353
"no item granting write access for deallocation to tag {:?} found in borrow stack" ,
349
354
tag,
350
- ) ) )
355
+ ) )
351
356
} ) ?;
352
357
353
358
// Step 2: Remove all items. Also checks for protectors.
@@ -369,9 +374,14 @@ impl<'tcx> Stack {
369
374
// Now we figure out which item grants our parent (`derived_from`) this kind of access.
370
375
// We use that to determine where to put the new item.
371
376
let granting_idx = self . find_granting ( access, derived_from)
372
- . ok_or_else ( || err_ub ! ( UbExperimental ( format!(
373
- "trying to reborrow for {:?}, but parent tag {:?} does not have an appropriate item in the borrow stack" , new. perm, derived_from,
374
- ) ) ) ) ?;
377
+ . ok_or_else ( ||
378
+ err_ub_experimental (
379
+ derived_from,
380
+ format ! (
381
+ "trying to reborrow for {:?}, but parent tag {:?} does not have an appropriate item in the borrow stack" ,
382
+ new. perm, derived_from,
383
+ ) ,
384
+ ) ) ?;
375
385
376
386
// Compute where to put the new item.
377
387
// Either way, we ensure that we insert the new item in a way such that between
@@ -638,3 +648,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
638
648
Ok ( ( ) )
639
649
}
640
650
}
651
+
652
+ fn err_ub_experimental ( tag : Tag , mut msg : String ) -> InterpErrorInfo < ' static > {
653
+ if let Tag :: Tagged ( id) = tag {
654
+ // FIXME: do not add this message when the flag is already set
655
+ write ! ( msg, " Rerun with `-Zmiri-track-pointer-tag={}` for more information" , id) . unwrap ( ) ;
656
+ }
657
+ err_ub ! ( UbExperimental ( msg) ) . into ( )
658
+ }
0 commit comments