From 732b71a1ba4de6a3ecaae5fe1c4e916a7dae33a0 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Wed, 12 Dec 2018 09:47:45 +0200 Subject: [PATCH] rustc: add a ty::RegionKind::display_outputs_anything method to avoid printing to a string. --- src/librustc/ty/print.rs | 15 ---- src/librustc/util/ppaux.rs | 142 +++++++++++++++++++++++++++++++------ 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 @@ pub(crate) fn prepare_late_bound_region_info(&mut self, value: &ty::Binder pub trait Print<'tcx> { fn print(&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( &self, f: &mut F, @@ -75,11 +70,6 @@ fn print_display( 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(&self, f: &mut F, cx: &mut PrintCx<'_, '_, 'tcx>) -> fmt::Result { let old_debug = cx.is_debug; cx.is_debug = true; @@ -87,9 +77,4 @@ fn print_debug(&self, f: &mut F, cx: &mut PrintCx<'_, '_, '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 @@ fn parameterized( 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()) -- 2.44.0