@@ -21,17 +21,87 @@ use syntax::ast::CRATE_NODE_ID;
2121use syntax:: symbol:: { Symbol , InternedString } ;
2222use hir;
2323
24+ /// The "region highlights" are used to control region printing during
25+ /// specific error messages. When a "region highlight" is enabled, it
26+ /// gives an alternate way to print specific regions. For now, we
27+ /// always print those regions using a number, so something like `'0`.
28+ ///
29+ /// Regions not selected by the region highlight mode are presently
30+ /// unaffected.
31+ #[ derive( Copy , Clone , Default ) ]
32+ pub struct RegionHighlightMode {
33+ /// If enabled, when we see the selected region inference
34+ /// variable, use `"'N"`; otherwise, use an empty string `""`
35+ /// (which is our ordinary behavior).
36+ highlight_region_vid : Option < ( RegionVid , usize ) > ,
37+
38+ /// If enabled, when printing a "free region" that originated from
39+ /// the given `ty::BoundRegion`, print it as `'1`. Free regions that would ordinarily
40+ /// have names print as normal.
41+ ///
42+ /// This is used when you have a signature like `fn foo(x: &u32,
43+ /// y: &'a u32)` and we want to give a name to the region of the
44+ /// reference `x`.
45+ highlight_bound_region : Option < ( ty:: BoundRegion , usize ) > ,
46+ }
47+
2448thread_local ! {
2549 /// Mechanism for highlighting of specific regions for display in NLL region inference errors.
2650 /// Contains region to highlight and counter for number to use when highlighting.
27- static HIGHLIGHT_REGION_FOR_REGIONVID : Cell <Option <( RegionVid , usize ) >> = Cell :: new( None )
51+ static REGION_HIGHLIGHT_MODE : Cell <RegionHighlightMode > =
52+ Cell :: new( RegionHighlightMode :: default ( ) )
2853}
2954
30- thread_local ! {
31- /// Mechanism for highlighting of specific regions for display in NLL's 'borrow does not live
32- /// long enough' errors. Contains a region to highlight and a counter to use.
33- static HIGHLIGHT_REGION_FOR_BOUND_REGION : Cell <Option <( ty:: BoundRegion , usize ) >> =
34- Cell :: new( None )
55+ impl RegionHighlightMode {
56+ pub fn get ( ) -> Self {
57+ REGION_HIGHLIGHT_MODE . with ( |c| c. get ( ) )
58+ }
59+
60+ fn set < R > (
61+ old_mode : Self ,
62+ new_mode : Self ,
63+ op : impl FnOnce ( ) -> R ,
64+ ) -> R {
65+ REGION_HIGHLIGHT_MODE . with ( |c| {
66+ c. set ( new_mode) ;
67+ let result = op ( ) ;
68+ c. set ( old_mode) ;
69+ result
70+ } )
71+ }
72+
73+ pub fn highlighting_region_vid < R > ( vid : RegionVid , number : usize , op : impl FnOnce ( ) -> R ) -> R {
74+ let old_mode = Self :: get ( ) ;
75+ assert ! ( old_mode. highlight_region_vid. is_none( ) ) ;
76+ Self :: set (
77+ old_mode,
78+ Self {
79+ highlight_region_vid : Some ( ( vid, number) ) ,
80+ ..old_mode
81+ } ,
82+ op,
83+ )
84+ }
85+
86+ /// During the execution of `op`, highlight the given bound
87+ /// region. We can only highlight one bound region at a time. See
88+ /// the field `highlight_bound_region` for more detailed notes.
89+ pub fn highlighting_bound_region < R > (
90+ br : ty:: BoundRegion ,
91+ number : usize ,
92+ op : impl FnOnce ( ) -> R ,
93+ ) -> R {
94+ let old_mode = Self :: get ( ) ;
95+ assert ! ( old_mode. highlight_bound_region. is_none( ) ) ;
96+ Self :: set (
97+ old_mode,
98+ Self {
99+ highlight_bound_region : Some ( ( br, number) ) ,
100+ ..old_mode
101+ } ,
102+ op,
103+ )
104+ }
35105}
36106
37107macro_rules! gen_display_debug_body {
@@ -553,42 +623,6 @@ pub fn parameterized<F: fmt::Write>(f: &mut F,
553623 PrintContext :: new ( ) . parameterized ( f, substs, did, projections)
554624}
555625
556- fn get_highlight_region_for_regionvid ( ) -> Option < ( RegionVid , usize ) > {
557- HIGHLIGHT_REGION_FOR_REGIONVID . with ( |hr| hr. get ( ) )
558- }
559-
560- pub fn with_highlight_region_for_regionvid < R > (
561- r : RegionVid ,
562- counter : usize ,
563- op : impl FnOnce ( ) -> R
564- ) -> R {
565- HIGHLIGHT_REGION_FOR_REGIONVID . with ( |hr| {
566- assert_eq ! ( hr. get( ) , None ) ;
567- hr. set ( Some ( ( r, counter) ) ) ;
568- let r = op ( ) ;
569- hr. set ( None ) ;
570- r
571- } )
572- }
573-
574- fn get_highlight_region_for_bound_region ( ) -> Option < ( ty:: BoundRegion , usize ) > {
575- HIGHLIGHT_REGION_FOR_BOUND_REGION . with ( |hr| hr. get ( ) )
576- }
577-
578- pub fn with_highlight_region_for_bound_region < R > (
579- r : ty:: BoundRegion ,
580- counter : usize ,
581- op : impl Fn ( ) -> R
582- ) -> R {
583- HIGHLIGHT_REGION_FOR_BOUND_REGION . with ( |hr| {
584- assert_eq ! ( hr. get( ) , None ) ;
585- hr. set ( Some ( ( r, counter) ) ) ;
586- let r = op ( ) ;
587- hr. set ( None ) ;
588- r
589- } )
590- }
591-
592626impl < ' a , T : Print > Print for & ' a T {
593627 fn print < F : fmt:: Write > ( & self , f : & mut F , cx : & mut PrintContext ) -> fmt:: Result {
594628 ( * self ) . print ( f, cx)
@@ -740,7 +774,7 @@ define_print! {
740774 return self . print_debug( f, cx) ;
741775 }
742776
743- if let Some ( ( region, counter) ) = get_highlight_region_for_bound_region ( ) {
777+ if let Some ( ( region, counter) ) = RegionHighlightMode :: get ( ) . highlight_bound_region {
744778 if * self == region {
745779 return match * self {
746780 BrNamed ( _, name) => write!( f, "{}" , name) ,
@@ -807,7 +841,7 @@ define_print! {
807841 }
808842 }
809843 ty:: ReVar ( region_vid) => {
810- if get_highlight_region_for_regionvid ( ) . is_some( ) {
844+ if RegionHighlightMode :: get ( ) . highlight_region_vid . is_some( ) {
811845 write!( f, "{:?}" , region_vid)
812846 } else if cx. identify_regions {
813847 write!( f, "'{}rv" , region_vid. index( ) )
@@ -944,7 +978,7 @@ impl fmt::Debug for ty::FloatVid {
944978
945979impl fmt:: Debug for ty:: RegionVid {
946980 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
947- if let Some ( ( region, counter) ) = get_highlight_region_for_regionvid ( ) {
981+ if let Some ( ( region, counter) ) = RegionHighlightMode :: get ( ) . highlight_region_vid {
948982 debug ! ( "RegionVid.fmt: region={:?} self={:?} counter={:?}" , region, self , counter) ;
949983 return if * self == region {
950984 write ! ( f, "'{:?}" , counter)
0 commit comments