44use std:: cell:: RefCell ;
55use std:: collections:: { HashMap , HashSet } ;
66use std:: fmt;
7+ use std:: fmt:: Write ;
78use std:: num:: NonZeroU64 ;
89use std:: rc:: Rc ;
910
@@ -278,10 +279,13 @@ impl<'tcx> Stack {
278279 if let Some ( call) = item. protector {
279280 if global. is_active ( call) {
280281 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+ ) ) ;
285289 } else {
286290 throw_ub ! ( UbExperimental ( format!(
287291 "deallocating while item is protected: {:?}" ,
@@ -300,10 +304,10 @@ impl<'tcx> Stack {
300304
301305 // Step 1: Find granting item.
302306 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+ )
307311 } ) ?;
308312
309313 // Step 2: Remove incompatible items above them. Make sure we do not remove protected
@@ -344,10 +348,11 @@ impl<'tcx> Stack {
344348 fn dealloc ( & mut self , tag : Tag , global : & GlobalState ) -> InterpResult < ' tcx > {
345349 // Step 1: Find granting item.
346350 self . find_granting ( AccessKind :: Write , tag) . ok_or_else ( || {
347- err_ub ! ( UbExperimental ( format!(
351+ err_ub_experimental (
352+ tag, format ! (
348353 "no item granting write access for deallocation to tag {:?} found in borrow stack" ,
349354 tag,
350- ) ) )
355+ ) )
351356 } ) ?;
352357
353358 // Step 2: Remove all items. Also checks for protectors.
@@ -369,9 +374,14 @@ impl<'tcx> Stack {
369374 // Now we figure out which item grants our parent (`derived_from`) this kind of access.
370375 // We use that to determine where to put the new item.
371376 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+ ) ) ?;
375385
376386 // Compute where to put the new item.
377387 // 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
638648 Ok ( ( ) )
639649 }
640650}
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