rustc: integrate LocalPathPrinter's behavior into FmtPrinter.

This commit is contained in:
Eduard-Mihai Burtescu 2018-12-19 14:49:32 +02:00
parent 9f8aaa04e0
commit b0fbca953f
2 changed files with 63 additions and 39 deletions

View File

@ -11,7 +11,7 @@ use rustc_data_structures::fx::FxHashSet;
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 @@ pub trait Print<'tcx, P> {
pub trait Printer: Sized {
type Path;
#[must_use]
fn print_def_path(
self: &mut PrintCx<'_, '_, 'tcx, Self>,
def_id: DefId,
@ -153,6 +154,7 @@ pub trait Printer: Sized {
) -> 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 @@ pub trait Printer: Sized {
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 @@ pub trait Printer: Sized {
) -> 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 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
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 @@ impl LocalPathPrinter {
}
}
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 @@ impl Printer for LocalPathPrinter {
// 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 @@ impl Printer for LocalPathPrinter {
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> {}

View File

@ -10,11 +10,11 @@ use crate::ty::{Param, Bound, RawPtr, Ref, Never, Tuple};
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 @@ macro_rules! gen_display_debug {
}
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 @@ impl<F: fmt::Write> PrintCx<'a, 'gcx, 'tcx, FmtPrinter<F>> {
}
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 @@ impl fmt::Debug for ty::GenericParamDef {
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 @@ impl fmt::Debug for ty::TraitDef {
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 @@ impl<'tcx> fmt::Debug for ty::ClosureUpvar<'tcx> {
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 @@ define_print! {
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",