@@ -488,6 +488,8 @@ struct DisplayFmtPadding {
488488 indent_middle : S ,
489489 /// Indentation for the last child.
490490 indent_last : S ,
491+ /// Replaces `join_last` for a wildcard root.
492+ wildcard_root : S ,
491493}
492494/// How to show whether a location has been accessed
493495///
@@ -561,6 +563,11 @@ impl DisplayFmt {
561563 } )
562564 . unwrap_or ( "" )
563565 }
566+
567+ /// Print extra text if the tag is exposed.
568+ fn print_exposed ( & self , exposed : bool ) -> S {
569+ if exposed { " (exposed)" } else { "" }
570+ }
564571}
565572
566573/// Track the indentation of the tree.
@@ -607,23 +614,21 @@ fn char_repeat(c: char, n: usize) -> String {
607614struct DisplayRepr {
608615 tag : BorTag ,
609616 name : Option < String > ,
617+ exposed : bool ,
610618 rperm : Vec < Option < LocationState > > ,
611619 children : Vec < DisplayRepr > ,
612620}
613621
614622impl DisplayRepr {
615- fn from ( tree : & Tree , show_unnamed : bool ) -> Option < Self > {
623+ fn from ( tree : & Tree , root : UniIndex , show_unnamed : bool ) -> Option < Self > {
616624 let mut v = Vec :: new ( ) ;
617- extraction_aux ( tree, tree . root , show_unnamed, & mut v) ;
625+ extraction_aux ( tree, root, show_unnamed, & mut v) ;
618626 let Some ( root) = v. pop ( ) else {
619627 if show_unnamed {
620628 unreachable ! (
621629 "This allocation contains no tags, not even a root. This should not happen."
622630 ) ;
623631 }
624- eprintln ! (
625- "This allocation does not contain named tags. Use `miri_print_borrow_state(_, true)` to also print unnamed tags."
626- ) ;
627632 return None ;
628633 } ;
629634 assert ! ( v. is_empty( ) ) ;
@@ -637,6 +642,7 @@ impl DisplayRepr {
637642 ) {
638643 let node = tree. nodes . get ( idx) . unwrap ( ) ;
639644 let name = node. debug_info . name . clone ( ) ;
645+ let exposed = node. is_exposed ;
640646 let children_sorted = {
641647 let mut children = node. children . iter ( ) . cloned ( ) . collect :: < Vec < _ > > ( ) ;
642648 children. sort_by_key ( |idx| tree. nodes . get ( * idx) . unwrap ( ) . tag ) ;
@@ -661,12 +667,13 @@ impl DisplayRepr {
661667 for child_idx in children_sorted {
662668 extraction_aux ( tree, child_idx, show_unnamed, & mut children) ;
663669 }
664- acc. push ( DisplayRepr { tag : node. tag , name, rperm, children } ) ;
670+ acc. push ( DisplayRepr { tag : node. tag , name, rperm, children, exposed } ) ;
665671 }
666672 }
667673 }
668674 fn print (
669- & self ,
675+ main_root : & Option < DisplayRepr > ,
676+ wildcard_subtrees : & [ DisplayRepr ] ,
670677 fmt : & DisplayFmt ,
671678 indenter : & mut DisplayIndent ,
672679 protected_tags : & FxHashMap < BorTag , ProtectorKind > ,
@@ -703,15 +710,41 @@ impl DisplayRepr {
703710 block. push ( s) ;
704711 }
705712 // This is the actual work
706- print_aux (
707- self ,
708- & range_padding,
709- fmt,
710- indenter,
711- protected_tags,
712- true , /* root _is_ the last child */
713- & mut block,
714- ) ;
713+ if let Some ( root) = main_root {
714+ print_aux (
715+ root,
716+ & range_padding,
717+ fmt,
718+ indenter,
719+ protected_tags,
720+ true , /* root _is_ the last child */
721+ false , /* not a wildcard_root*/
722+ & mut block,
723+ ) ;
724+ }
725+ for tree in wildcard_subtrees. iter ( ) {
726+ let mut gap_line = String :: new ( ) ;
727+ gap_line. push_str ( fmt. perm . open ) ;
728+ for ( i, & pad) in range_padding. iter ( ) . enumerate ( ) {
729+ if i > 0 {
730+ gap_line. push_str ( fmt. perm . sep ) ;
731+ }
732+ gap_line. push_str ( & format ! ( "{}{}" , char_repeat( ' ' , pad) , " " ) ) ;
733+ }
734+ gap_line. push_str ( fmt. perm . close ) ;
735+ block. push ( gap_line) ;
736+
737+ print_aux (
738+ tree,
739+ & range_padding,
740+ fmt,
741+ indenter,
742+ protected_tags,
743+ true , /* root _is_ the last child */
744+ true , /* wildcard_root*/
745+ & mut block,
746+ ) ;
747+ }
715748 // Then it's just prettifying it with a border of dashes.
716749 {
717750 let wr = & fmt. wrapper ;
@@ -741,6 +774,7 @@ impl DisplayRepr {
741774 indent : & mut DisplayIndent ,
742775 protected_tags : & FxHashMap < BorTag , ProtectorKind > ,
743776 is_last_child : bool ,
777+ is_wildcard_root : bool ,
744778 acc : & mut Vec < String > ,
745779 ) {
746780 let mut line = String :: new ( ) ;
@@ -760,7 +794,9 @@ impl DisplayRepr {
760794 indent. write ( & mut line) ;
761795 {
762796 // padding
763- line. push_str ( if is_last_child {
797+ line. push_str ( if is_wildcard_root {
798+ fmt. padding . wildcard_root
799+ } else if is_last_child {
764800 fmt. padding . join_last
765801 } else {
766802 fmt. padding . join_middle
@@ -777,12 +813,22 @@ impl DisplayRepr {
777813 line. push_str ( & fmt. print_tag ( tree. tag , & tree. name ) ) ;
778814 let protector = protected_tags. get ( & tree. tag ) ;
779815 line. push_str ( fmt. print_protector ( protector) ) ;
816+ line. push_str ( fmt. print_exposed ( tree. exposed ) ) ;
780817 // Push the line to the accumulator then recurse.
781818 acc. push ( line) ;
782819 let nb_children = tree. children . len ( ) ;
783820 for ( i, child) in tree. children . iter ( ) . enumerate ( ) {
784821 indent. increment ( fmt, is_last_child) ;
785- print_aux ( child, padding, fmt, indent, protected_tags, i + 1 == nb_children, acc) ;
822+ print_aux (
823+ child,
824+ padding,
825+ fmt,
826+ indent,
827+ protected_tags,
828+ /* is_last_child */ i + 1 == nb_children,
829+ /* is_wildcard_root */ false ,
830+ acc,
831+ ) ;
786832 indent. decrement ( fmt) ;
787833 }
788834 }
@@ -803,6 +849,7 @@ const DEFAULT_FORMATTER: DisplayFmt = DisplayFmt {
803849 indent_last : " " ,
804850 join_haschild : "┬" ,
805851 join_default : "─" ,
852+ wildcard_root : "*" ,
806853 } ,
807854 accessed : DisplayFmtAccess { yes : " " , no : "?" , meh : "-" } ,
808855} ;
@@ -816,15 +863,27 @@ impl<'tcx> Tree {
816863 ) -> InterpResult < ' tcx > {
817864 let mut indenter = DisplayIndent :: new ( ) ;
818865 let ranges = self . locations . iter_all ( ) . map ( |( range, _loc) | range) . collect :: < Vec < _ > > ( ) ;
819- if let Some ( repr) = DisplayRepr :: from ( self , show_unnamed) {
820- repr. print (
821- & DEFAULT_FORMATTER ,
822- & mut indenter,
823- protected_tags,
824- ranges,
825- /* print warning message about tags not shown */ !show_unnamed,
866+ let main_tree = DisplayRepr :: from ( self , self . roots [ 0 ] , show_unnamed) ;
867+ let wildcard_subtrees = self . roots [ 1 ..]
868+ . iter ( )
869+ . filter_map ( |root| DisplayRepr :: from ( self , * root, show_unnamed) )
870+ . collect :: < Vec < _ > > ( ) ;
871+
872+ if main_tree. is_none ( ) && wildcard_subtrees. is_empty ( ) {
873+ eprintln ! (
874+ "This allocation does not contain named tags. Use `miri_print_borrow_state(_, true)` to also print unnamed tags."
826875 ) ;
827876 }
877+
878+ DisplayRepr :: print (
879+ & main_tree,
880+ wildcard_subtrees. as_slice ( ) ,
881+ & DEFAULT_FORMATTER ,
882+ & mut indenter,
883+ protected_tags,
884+ ranges,
885+ /* print warning message about tags not shown */ !show_unnamed,
886+ ) ;
828887 interp_ok ( ( ) )
829888 }
830889}
0 commit comments