about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorEduard-Mihai Burtescu <edy.burt@gmail.com>2018-12-12 09:47:45 +0200
committerEduard-Mihai Burtescu <edy.burt@gmail.com>2019-03-15 09:26:13 +0200
commit732b71a1ba4de6a3ecaae5fe1c4e916a7dae33a0 (patch)
treef80bf6e40b4f1a5e19c2a1a2525ce2ea98b9d4f7 /src
parent329b8ca8180ef8aa7314bd0bff9d9cd61f8dad40 (diff)
downloadrust-732b71a1ba4de6a3ecaae5fe1c4e916a7dae33a0.tar.gz
rust-732b71a1ba4de6a3ecaae5fe1c4e916a7dae33a0.zip
rustc: add a ty::RegionKind::display_outputs_anything method to avoid printing to a string.
Diffstat (limited to 'src')
-rw-r--r--src/librustc/ty/print.rs15
-rw-r--r--src/librustc/util/ppaux.rs142
2 files changed, 120 insertions, 37 deletions
diff --git a/src/librustc/ty/print.rs b/src/librustc/ty/print.rs
index 81101740a4c..7085a3beb1c 100644
--- a/src/librustc/ty/print.rs
+++ b/src/librustc/ty/print.rs
@@ -59,11 +59,6 @@ impl PrintCx<'a, 'gcx, 'tcx> {
 
 pub trait Print<'tcx> {
     fn print<F: fmt::Write>(&self, f: &mut F, cx: &mut PrintCx<'_, '_, 'tcx>) -> fmt::Result;
-    fn print_to_string(&self, cx: &mut PrintCx<'_, '_, 'tcx>) -> String {
-        let mut result = String::new();
-        let _ = self.print(&mut result, cx);
-        result
-    }
     fn print_display<F: fmt::Write>(
         &self,
         f: &mut F,
@@ -75,11 +70,6 @@ pub trait Print<'tcx> {
         cx.is_debug = old_debug;
         result
     }
-    fn print_display_to_string(&self, cx: &mut PrintCx<'_, '_, 'tcx>) -> String {
-        let mut result = String::new();
-        let _ = self.print_display(&mut result, cx);
-        result
-    }
     fn print_debug<F: fmt::Write>(&self, f: &mut F, cx: &mut PrintCx<'_, '_, 'tcx>) -> fmt::Result {
         let old_debug = cx.is_debug;
         cx.is_debug = true;
@@ -87,9 +77,4 @@ pub trait Print<'tcx> {
         cx.is_debug = old_debug;
         result
     }
-    fn print_debug_to_string(&self, cx: &mut PrintCx<'_, '_, 'tcx>) -> String {
-        let mut result = String::new();
-        let _ = self.print_debug(&mut result, cx);
-        result
-    }
 }
diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs
index 2a03f32fdcc..a0feeae0a0c 100644
--- a/src/librustc/util/ppaux.rs
+++ b/src/librustc/util/ppaux.rs
@@ -396,20 +396,15 @@ impl PrintCx<'a, 'gcx, 'tcx> {
                         continue;
                     }
                     start_or_continue(f, start, ", ")?;
-                    if self.is_verbose {
-                        write!(f, "{:?}", region)?;
+                    if !region.display_outputs_anything(self) {
+                        // This happens when the value of the region
+                        // parameter is not easily serialized. This may be
+                        // because the user omitted it in the first place,
+                        // or because it refers to some block in the code,
+                        // etc. I'm not sure how best to serialize this.
+                        write!(f, "'_")?;
                     } else {
-                        let s = region.print_display_to_string(self);
-                        if s.is_empty() {
-                            // This happens when the value of the region
-                            // parameter is not easily serialized. This may be
-                            // because the user omitted it in the first place,
-                            // or because it refers to some block in the code,
-                            // etc. I'm not sure how best to serialize this.
-                            write!(f, "'_")?;
-                        } else {
-                            write!(f, "{}", s)?;
-                        }
+                        region.print_display(f, self)?;
                     }
                 }
                 UnpackedKind::Type(ty) => {
@@ -727,6 +722,32 @@ define_print! {
     }
 }
 
+// HACK(eddyb) (see `ty::RegionKind::display_outputs_anything`)
+//
+// NB: this must be kept in sync with the printing logic above.
+impl ty::BoundRegion {
+    fn display_outputs_anything(&self, cx: &mut PrintCx<'_, '_, '_>) -> bool {
+        if cx.is_verbose {
+            return true;
+        }
+
+        if let BrNamed(_, name) = *self {
+            if name != "" && name != "'_" {
+                return true;
+            }
+        }
+
+        let highlight = RegionHighlightMode::get();
+        if let Some((region, _)) = highlight.highlight_bound_region {
+            if *self == region {
+                return true;
+            }
+        }
+
+        false
+    }
+}
+
 define_print! {
     () ty::PlaceholderRegion, (self, f, cx) {
         display {
@@ -744,6 +765,24 @@ define_print! {
     }
 }
 
+// HACK(eddyb) (see `ty::RegionKind::display_outputs_anything`)
+//
+// NB: this must be kept in sync with the printing logic above.
+impl ty::PlaceholderRegion {
+    fn display_outputs_anything(&self, cx: &mut PrintCx<'_, '_, '_>) -> bool {
+        if cx.is_verbose {
+            return true;
+        }
+
+        let highlight = RegionHighlightMode::get();
+        if highlight.placeholder_highlight(*self).is_some() {
+            return true;
+        }
+
+        self.name.display_outputs_anything(cx)
+    }
+}
+
 define_print! {
     () ty::RegionKind, (self, f, cx) {
         display {
@@ -851,6 +890,49 @@ define_print! {
     }
 }
 
+// HACK(eddyb) Trying to print a lifetime might not print anything, which
+// may need special handling in the caller (of `ty::RegionKind::print`).
+// To avoid printing to a temporary string, the `display_outputs_anything`
+// method can instead be used to determine this, ahead of time.
+//
+// NB: this must be kept in sync with the printing logic above.
+impl ty::RegionKind {
+    fn display_outputs_anything(&self, cx: &mut PrintCx<'_, '_, '_>) -> bool {
+        if cx.is_verbose {
+            return true;
+        }
+
+        if RegionHighlightMode::get().region_highlighted(self).is_some() {
+            return true;
+        }
+
+        match *self {
+            ty::ReEarlyBound(ref data) => {
+                data.name != "" && data.name != "'_"
+            }
+
+            ty::ReLateBound(_, br) |
+            ty::ReFree(ty::FreeRegion { bound_region: br, .. }) => {
+                br.display_outputs_anything(cx)
+            }
+
+            ty::RePlaceholder(p) => p.display_outputs_anything(cx),
+
+            ty::ReScope(_) |
+            ty::ReVar(_) if cx.identify_regions => true,
+
+            ty::ReVar(region_vid) => region_vid.display_outputs_anything(cx),
+
+            ty::ReScope(_) |
+            ty::ReErased => false,
+
+            ty::ReStatic |
+            ty::ReEmpty |
+            ty::ReClosureBound(_) => true,
+        }
+    }
+}
+
 define_print! {
     () ty::FreeRegion, (self, f, cx) {
         debug {
@@ -943,6 +1025,24 @@ define_print! {
     }
 }
 
+// HACK(eddyb) (see `ty::RegionKind::display_outputs_anything`)
+//
+// NB: this must be kept in sync with the printing logic above.
+impl ty::RegionVid {
+    fn display_outputs_anything(&self, cx: &mut PrintCx<'_, '_, '_>) -> bool {
+        if cx.is_verbose {
+            return true;
+        }
+
+        let highlight = RegionHighlightMode::get();
+        if highlight.region_highlighted(&ty::ReVar(*self)).is_some() {
+            return true;
+        }
+
+        false
+    }
+}
+
 define_print! {
     () ty::InferTy, (self, f, cx) {
         display {
@@ -1053,9 +1153,8 @@ define_print! {
                 }
                 Ref(r, ty, mutbl) => {
                     write!(f, "&")?;
-                    let s = r.print_display_to_string(cx);
-                    if !s.is_empty() {
-                        write!(f, "{} ", s)?;
+                    if r.display_outputs_anything(cx) {
+                        print!(f, cx, print_display(r), write(" "))?;
                     }
                     ty::TypeAndMut { ty, mutbl }.print(f, cx)
                 }
@@ -1101,17 +1200,16 @@ define_print! {
                 }
                 Adt(def, substs) => cx.parameterized(f, def.did, substs, iter::empty()),
                 Dynamic(data, r) => {
-                    let r = r.print_display_to_string(cx);
-                    if !r.is_empty() {
+                    let print_r = r.display_outputs_anything(cx);
+                    if print_r {
                         write!(f, "(")?;
                     }
                     write!(f, "dyn ")?;
                     data.print(f, cx)?;
-                    if !r.is_empty() {
-                        write!(f, " + {})", r)
-                    } else {
-                        Ok(())
+                    if print_r {
+                        print!(f, cx, write(" + "), print_display(r), write(")"))?;
                     }
+                    Ok(())
                 }
                 Foreign(def_id) => {
                     cx.parameterized(f, def_id, subst::InternalSubsts::empty(), iter::empty())