]> git.lizzy.rs Git - rust.git/commitdiff
rustc: integrate LocalPathPrinter's behavior into FmtPrinter.
authorEduard-Mihai Burtescu <edy.burt@gmail.com>
Wed, 19 Dec 2018 12:49:32 +0000 (14:49 +0200)
committerEduard-Mihai Burtescu <edy.burt@gmail.com>
Fri, 15 Mar 2019 11:25:10 +0000 (13:25 +0200)
src/librustc/ty/print.rs
src/librustc/util/ppaux.rs

index 053a7531cadd66c986888c1731b4bcf8ecaf4c94..de0c3ee7fff8e8bd70c01745c484db484b39ab4a 100644 (file)
@@ -11,7 +11,7 @@
 use syntax::symbol::InternedString;
 
 use std::cell::Cell;
-use std::fmt;
+use std::fmt::{self, Write as _};
 use std::ops::Deref;
 
 thread_local! {
@@ -145,6 +145,7 @@ fn print_debug(&self, cx: &mut PrintCx<'_, '_, 'tcx, P>) -> Self::Output {
 pub trait Printer: Sized {
     type Path;
 
+    #[must_use]
     fn print_def_path(
         self: &mut PrintCx<'_, '_, 'tcx, Self>,
         def_id: DefId,
@@ -153,6 +154,7 @@ fn print_def_path(
     ) -> Self::Path {
         self.default_print_def_path(def_id, substs, ns)
     }
+    #[must_use]
     fn print_impl_path(
         self: &mut PrintCx<'_, '_, 'tcx, Self>,
         impl_def_id: DefId,
@@ -162,8 +164,11 @@ fn print_impl_path(
         self.default_print_impl_path(impl_def_id, substs, ns)
     }
 
+    #[must_use]
     fn path_crate(self: &mut PrintCx<'_, '_, '_, Self>, cnum: CrateNum) -> Self::Path;
+    #[must_use]
     fn path_impl(self: &mut PrintCx<'_, '_, '_, Self>, text: &str) -> Self::Path;
+    #[must_use]
     fn path_append(
         self: &mut PrintCx<'_, '_, '_, Self>,
         path: Self::Path,
@@ -171,6 +176,14 @@ fn path_append(
     ) -> Self::Path;
 }
 
+#[must_use]
+pub struct PrettyPath {
+    pub empty: bool,
+}
+
+/// Trait for printers that pretty-print using `fmt::Write` to the printer.
+pub trait PrettyPrinter: Printer<Path = Result<PrettyPath, fmt::Error>> + fmt::Write {}
+
 impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
     // HACK(eddyb) get rid of `def_path_str` and/or pass `Namespace` explicitly always
     // (but also some things just print a `DefId` generally so maybe we need this?)
@@ -202,7 +215,10 @@ pub fn def_path_str_with_substs_and_ns(
         if FORCE_ABSOLUTE.with(|force| force.get()) {
             PrintCx::new(self, AbsolutePathPrinter).print_def_path(def_id, substs, ns)
         } else {
-            PrintCx::new(self, LocalPathPrinter).print_def_path(def_id, substs, ns)
+            let mut s = String::new();
+            let _ = PrintCx::new(self, FmtPrinter { fmt: &mut s })
+                .print_def_path(def_id, substs, ns);
+            s
         }
     }
 
@@ -442,10 +458,7 @@ pub struct FmtPrinter<F: fmt::Write> {
     pub fmt: F,
 }
 
-// FIXME(eddyb) integrate into `FmtPrinter`.
-struct LocalPathPrinter;
-
-impl LocalPathPrinter {
+impl<F: fmt::Write> FmtPrinter<F> {
     /// If possible, this returns a global path resolving to `def_id` that is visible
     /// from at least one local module and returns true. If the crate defining `def_id` is
     /// declared with an `extern crate`, the path is guaranteed to use the `extern crate`.
@@ -582,8 +595,14 @@ fn try_print_visible_def_path(
     }
 }
 
-impl Printer for LocalPathPrinter {
-    type Path = String;
+impl<F: fmt::Write> fmt::Write for FmtPrinter<F> {
+    fn write_str(&mut self, s: &str) -> fmt::Result {
+        self.fmt.write_str(s)
+    }
+}
+
+impl<F: fmt::Write> Printer for FmtPrinter<F> {
+    type Path = Result<PrettyPath, fmt::Error>;
 
     fn print_def_path(
         self: &mut PrintCx<'_, '_, 'tcx, Self>,
@@ -612,7 +631,6 @@ fn print_impl_path(
             // If no type info is available, fall back to
             // pretty printing some span information. This should
             // only occur very early in the compiler pipeline.
-            // FIXME(eddyb) this should just be using `tcx.def_span(impl_def_id)`
             let parent_def_id = self.tcx.parent(impl_def_id).unwrap();
             let path = self.print_def_path(parent_def_id, None, ns);
             let span = self.tcx.def_span(impl_def_id);
@@ -627,26 +645,39 @@ fn path_crate(self: &mut PrintCx<'_, '_, '_, Self>, cnum: CrateNum) -> Self::Pat
             if self.tcx.sess.rust_2018() {
                 // We add the `crate::` keyword on Rust 2018, only when desired.
                 if SHOULD_PREFIX_WITH_CRATE.with(|flag| flag.get()) {
-                    return keywords::Crate.name().to_string();
+                    write!(self.printer, "{}", keywords::Crate.name())?;
+                    return Ok(PrettyPath { empty: false });
                 }
             }
-            String::new()
+            Ok(PrettyPath { empty: true })
         } else {
-            self.tcx.crate_name(cnum).to_string()
+            write!(self.printer, "{}", self.tcx.crate_name(cnum))?;
+            Ok(PrettyPath { empty: false })
         }
     }
     fn path_impl(self: &mut PrintCx<'_, '_, '_, Self>, text: &str) -> Self::Path {
-        text.to_string()
+        write!(self.printer, "{}", text)?;
+        Ok(PrettyPath { empty: false })
     }
     fn path_append(
         self: &mut PrintCx<'_, '_, '_, Self>,
-        mut path: Self::Path,
+        path: Self::Path,
         text: &str,
     ) -> Self::Path {
-        if !path.is_empty() {
-            path.push_str("::");
+        let path = path?;
+
+        // FIXME(eddyb) this shouldn't happen, but is currently
+        // the case for `extern { ... }` "foreign modules".
+        if text.is_empty() {
+            return Ok(path);
         }
-        path.push_str(text);
-        path
+
+        if !path.empty {
+            write!(self.printer, "::")?;
+        }
+        write!(self.printer, "{}", text)?;
+        Ok(PrettyPath { empty: false })
     }
 }
+
+impl<F: fmt::Write> PrettyPrinter for FmtPrinter<F> {}
index cf92ab2f2ff4791885e493541e79766d42fd1163..39e26f13233b34e360fd3c42efbe62d779c6ac33 100644 (file)
 use crate::ty::{Closure, Generator, GeneratorWitness, Foreign, Projection, Opaque};
 use crate::ty::{Placeholder, UnnormalizedProjection, Dynamic, Int, Uint, Infer};
 use crate::ty::{self, ParamConst, Ty, TypeFoldable};
-use crate::ty::print::{FmtPrinter, PrintCx, Print};
+use crate::ty::print::{FmtPrinter, PrettyPrinter, PrintCx, Print};
 use crate::mir::interpret::ConstValue;
 
 use std::cell::Cell;
-use std::fmt;
+use std::fmt::{self, Write as _};
 use std::iter;
 use std::usize;
 
@@ -193,18 +193,18 @@ impl fmt::Debug for $target {
 }
 macro_rules! gen_print_impl {
     ( ($($x:tt)+) $target:ty, ($self:ident, $cx:ident) $disp:block $dbg:block ) => {
-        impl<$($x)+, F: fmt::Write> Print<'tcx, FmtPrinter<F>> for $target {
+        impl<$($x)+, P: PrettyPrinter> Print<'tcx, P> for $target {
             type Output = fmt::Result;
-            fn print(&$self, $cx: &mut PrintCx<'_, '_, 'tcx, FmtPrinter<F>>) -> fmt::Result {
+            fn print(&$self, $cx: &mut PrintCx<'_, '_, 'tcx, P>) -> fmt::Result {
                 if $cx.is_debug $dbg
                 else $disp
             }
         }
     };
     ( () $target:ty, ($self:ident, $cx:ident) $disp:block $dbg:block ) => {
-        impl<F: fmt::Write> Print<'tcx, FmtPrinter<F>> for $target {
+        impl<P: PrettyPrinter> Print<'tcx, P> for $target {
             type Output = fmt::Result;
-            fn print(&$self, $cx: &mut PrintCx<'_, '_, 'tcx, FmtPrinter<F>>) -> fmt::Result {
+            fn print(&$self, $cx: &mut PrintCx<'_, '_, 'tcx, P>) -> fmt::Result {
                 if $cx.is_debug $dbg
                 else $disp
             }
@@ -235,7 +235,7 @@ macro_rules! define_print {
     ( $generic:tt $target:ty,
       ($self:ident, $cx:ident) { display $disp:block } ) => {
         gen_print_impl! { $generic $target, ($self, $cx) yes $disp no {
-            write!($cx.printer.fmt, "{:?}", $self)
+            write!($cx.printer, "{:?}", $self)
         } }
     };
 }
@@ -246,7 +246,7 @@ macro_rules! define_print_multi {
 }
 macro_rules! print_inner {
     ( $cx:expr, write ($($data:expr),+) ) => {
-        write!($cx.printer.fmt, $($data),+)
+        write!($cx.printer, $($data),+)
     };
     ( $cx:expr, $kind:ident ($data:expr) ) => {
         $data.$kind($cx)
@@ -258,7 +258,7 @@ macro_rules! print {
     };
 }
 
-impl<F: fmt::Write> PrintCx<'a, 'gcx, 'tcx, FmtPrinter<F>> {
+impl<P: PrettyPrinter> PrintCx<'a, 'gcx, 'tcx, P> {
     fn fn_sig(
         &mut self,
         inputs: &[Ty<'tcx>],
@@ -409,7 +409,7 @@ fn parameterized(
     }
 
     fn in_binder<T>(&mut self, value: &ty::Binder<T>) -> fmt::Result
-        where T: Print<'tcx, FmtPrinter<F>, Output = fmt::Result> + TypeFoldable<'tcx>
+        where T: Print<'tcx, P, Output = fmt::Result> + TypeFoldable<'tcx>
     {
         fn name_by_region_index(index: usize) -> InternedString {
             match index {
@@ -494,13 +494,6 @@ pub fn parameterized<F: fmt::Write>(
     })
 }
 
-impl<'a, 'tcx, P, T: Print<'tcx, P>> Print<'tcx, P> for &'a T {
-    type Output = T::Output;
-    fn print(&self, cx: &mut PrintCx<'_, '_, 'tcx, P>) -> Self::Output {
-        (*self).print(cx)
-    }
-}
-
 define_print! {
     ('tcx) &'tcx ty::List<ty::ExistentialPredicate<'tcx>>, (self, cx) {
         display {
@@ -581,7 +574,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 
 impl fmt::Debug for ty::TraitDef {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        PrintCx::with(FmtPrinter { fmt: f }, |cx| {
+        PrintCx::with(FmtPrinter { fmt: f }, |mut cx| {
             print!(cx, write("{}", cx.tcx.def_path_str(self.def_id)))
         })
     }
@@ -589,7 +582,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 
 impl fmt::Debug for ty::AdtDef {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        PrintCx::with(FmtPrinter { fmt: f }, |cx| {
+        PrintCx::with(FmtPrinter { fmt: f }, |mut cx| {
             print!(cx, write("{}", cx.tcx.def_path_str(self.did)))
         })
     }
@@ -605,7 +598,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 
 impl fmt::Debug for ty::UpvarId {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        PrintCx::with(FmtPrinter { fmt: f }, |cx| {
+        PrintCx::with(FmtPrinter { fmt: f }, |mut cx| {
             print!(cx, write("UpvarId({:?};`{}`;{:?})",
                 self.var_path.hir_id,
                 cx.tcx.hir().name_by_hir_id(self.var_path.hir_id),
@@ -928,7 +921,7 @@ fn display_outputs_anything<P>(&self, cx: &mut PrintCx<'_, '_, '_, P>) -> bool {
 define_print! {
     () ty::Variance, (self, cx) {
         debug {
-            cx.printer.fmt.write_str(match *self {
+            cx.printer.write_str(match *self {
                 ty::Covariant => "+",
                 ty::Contravariant => "-",
                 ty::Invariant => "o",