]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc/util/ppaux.rs
rustc: add a ty::RegionKind::display_outputs_anything method to avoid printing to...
[rust.git] / src / librustc / util / ppaux.rs
index 2a03f32fdccdff68efd47040ff61b4d383238c9a..a0feeae0a0cc881e255715e0e49a8e597fe14d0a 100644 (file)
@@ -396,20 +396,15 @@ fn parameterized<F: fmt::Write>(
                         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 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
     }
 }
 
+// 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 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
     }
 }
 
+// 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 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
     }
 }
 
+// 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 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
     }
 }
 
+// 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 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
                 }
                 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 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
                 }
                 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())